###### tags: `WEPPO`, `semestr 5` # Lista 2 (8 listopada 2022) ### Zadanie 1 (2 pkt) :heavy_check_mark: ### Zadanie 2 (2 pkt) :heavy_check_mark: > Jakie są różnice między dwoma sposobami odwoływania się do części składowych obiektu (`.` vs `[]`)? Na podstawie [artykułu w Medium](https://javascript.plainenglish.io/javascript-dot-notation-vs-bracket-notation-which-to-use-when-e24117e44d71): główną zaletą notacji z nawiasami kwadratowymi jest to, że można wykorzystać zmienne (parametry) do wyciągania odpowiedniego pola z obiektu. Podobnie możemy używać w nazwie własności znaków specjalnych i spacji. ```javascript let person = { name = 'Magda', favColour = 'purple' }; console.log(person.name); // Magda person['Nowe pole'] = 34; console.log(person['Nowe pole']); // 34 ``` > Użycie argumentów innego typu niż `string` dla operatora `[]` dostępu do składowej obiektu. ```javascript let example = {}; example.whatever = 0; console.log(example.whatever); ``` > * Co się dzieje jeśli argumentem operatora jest liczba? Taka liczba zostaje zamieniona na napis. ```javascript let exampleA = {}; exampleA[0] = 'Magda?'; exampleA['0'] = 'Magda!'; console.log(exampleA); ``` > * Co się dzieje jeśli argumentem operatora jest inny obiekt? Taki obiekt również zostaje przekształcony w napis. ```javascript let exampleB = {}; exampleB[exampleA] = 'some string...'; exampleB['exampleA'] = 'some other string'; console.log(exampleB); ``` > * Jaki wpływ na klucz pod jakim zapisana zostanie wartość ma programista w obu przypadkach? Programista ma podgląd i możliwość modyfikacji metody `toString`, która odpowiada za to, jak obiekt zostanie przetłumaczony na napis. Przykładowo możemy użyć autorskiej implementacji tej funkcji, żeby nadpisać wartość: ```javascript exampleA.toString = function() { return 'This is an object (type A)!'; }; exampleB['This is an object (type A)!'] = 'yet another string!'; console.log(exampleB); ``` W przypadku liczb czy innych obiektów wbudowanych musi polegać na metodach konwersji zawartych w języku. > Użycie argumentów innego typu niż `number` dla operatora `[]` dostępu do tablicy. > * Co się dzieje jeśli argumentem operatora jest napis? Taki napis rzutowany jest na poprawną liczbę, o ile jest to możliwe. ```javascript let array = [0, 2, 4, 6, 8, 10]; console.log(array['5']); // 10 ``` > * Co się dzieje jeśli argumentem operatora jest inny obiekt? Jeśli konwersja na liczbę nie jest możliwa, to otrzymamy wartość `undefined`. ```javascript console.log(array[exampleA]) // undefined ``` > * Czy i jak zmienia się zawartość tablicy jeśli zostanie do niej dopisana właściwość pod kluczem, który nie jest liczbą? Zachowanie jest podobne jak wcześniej - dla obiektów zezwalających na konwersję na liczbę tablica zostaje odpowiednio rozszerzona, dla pozostałych zostaje przekształcona na bardziej ogólny obiekt i wtedy rozszerzona o kolejny klucz. ```javascript array['10'] = 20; console.log(array); // [ 0, 2, 4, 6, 8, 10, <4 empty items>, 20 ] array[exampleB] = 40; console.log(array); // [ 0, 2, 4, 6, 8, 10, <4 empty items>, 20, '[object Object]': 40 ] ``` > * Czy można ustawiać wartość atrybutu length tablicy na inną wartość niż liczba elementów w tej tablicy? Co się dzieje jeśli ustawia się wartość mniejszą niż liczba elementów, a co jeśli ustawia się wartość większą niż liczba elementów? Własność `length` można dowolnie modyfikować. W przypadku ustawienia na wartość mniejszą niż rzeczywista, dalsze elementy zostają ucięte. Jeśli wartość jest większa, to tablica zostaje rozszerzona o potrzebną liczbę pustych elementów. ```javascript array = [1, 2, 3, 4, 5, 6]; array.length = 3; console.log(array); // [ 1, 2, 3 ] array.length = 10; console.log(array); // [ 1, 2, 3, <7 empty items> ] console.log(array[9]); // undefined ``` ### Zadanie 3 (2 pkt) :white_check_mark: Ważne zasady: * `[]` oznacza pustą tablicę, zrzutowana na wartość boolowską daje `true`, na liczbę daje `0`, a na napis `''` * `+` na liczbach oznacza dodawanie (jeśli występuje jako operator unarny oznacza rzutowanie na liczbę), a na wartościach `string` konkatenację (podobnie jest przy tablicach, ale najpierw obie rzutowane są na napisy) * `!` przed wartością `boolean` zwraca jej zaprzeczenie * nawiasay okrągłe `()` służą tylko do oddzielenia fragmentów od siebie ```javascript console.log( (![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]] ); ------------- --------------- --------------------------- ------------------- 1) 2) 3) 4) ``` 1. `'false'[0] => 'f'` 2. `'false'[1] => 'a'` 3. `'falseundefined'[10] => 'i'` 4. `'false'[2] => 'l'` ### Zadanie 4 (1 pkt) :white_check_mark: > Wyjaśnić różnice między operatorami `typeof` i `instanceof`. Główną róznicą jest to, że `instanceof` pozwala konstruować warunki oparte o to, czy jakaś zmienna na pewno jest pożądanego typu. Natomiast `typeof` zwraca typ podanego wyrażenia jako napis. Powoduje to, że nadają się do różnych scenariuszy logicznych. ```javascript console.log(new Number(40) instanceof String); // false console.log(new String('Magda') instanceof String); // true console.log(typeof 190); // number console.log(typeof 'Magda'); // string console.log(typeof true); // boolean ``` Do tego operator `typeof` służy przede wszystkim do sprawdzania i porównywania typów podstawowych (`string`, `number` itd.), a `instanceof` nadaje się do porównywania bardziej złożonych obiektów. ### Zadanie 5 (1 pkt) :white_check_mark: > Pokazać jak zdefiniować nowy obiekt zawierający co najmniej jedno pole, jedną metodę oraz właściwości z akcesorami `get` i `set`. Pokazać jak do istniejącego obiektu dodać nowe pole, nową metodę i nową właściwość z akcesorami `get` i `set`. > > *Uwaga.* Do dodawania nowych składowych do istniejących obiektów można użyć metody `Object.defineProperty`. Które z w/w rodzajów składowych (pole, metoda, właściwość) mogą być dodawane w ten sposób, a które muszą być dodawane w ten sposób (bo inaczej się nie da)? ```javascript const person = { firstName: 'Magdalena', age: 21, favouriteColour: 'purple', get howOld() { return this.age; }, set howOld(newAge) { this.age = newAge; }, get favColour() { return this.favouriteColour; }, set favColour(newFavouriteColour) { this.favouriteColour = newFavouriteColour; }, introduction: function() { return this.firstName + ' (' + this.age + ')'; } }; console.log(person); ``` Nawet do istniejącego już obiektu możemy dodać nową metodę: ```javascript person.askFavouriteColour = function() { return ("Hi! My name's " + this.firstName + " and my favourite colour is " + this.favouriteColour + ". What's yours?"); }; console.log(person.askFavouriteColour()); ``` Funkcja `Object.defineProperty` może być wykorzystana do modyfikowania wszystkich typów składowych - pól, metod i własności. W przypadku własności, muszą być one dodane w ten sposób.