###### 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.