---
# System prepended metadata

title: Lista 2 (8 listopada 2022)
tags: [semestr 5, WEPPO]

---

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