# Czym jest this ?
Słowo kluczowe this jest wskaźnikiem wskazującym na obiekt, który wywołał funkcję.
TIP
Niestety this w JavaScripcie moze wskazywać na różne wartości w zależnosci od miejsca (kontekstu) w ktorym zostal wywolany (execution context) - aczkolwiek ostatecznie this jest określany przez sposob w jaki jest wykonywana dana funkcja - tzn, że jesteśmy w stanie sami określić i przekazać konteskt - za pomocą funkcji takich jak bind, apply czy call.
Aby dobrze zrozumieć oraz wiedzieć na co w danym momencie będzie wskazywał this zapoznaj się z poniższymi zadaniami. Spróbój samemu odgadnąć czym będzie this a następnie odkomentuj wywołanie kodu.
Wszystkie zadania są dostępne też tutaj: https://codesandbox.io/s/js-this-forked-mxeqc?file=/index.html (opens new window)
# 1. Person
// 1. Co będzie wynikiem wywołania person.greet() ?
// 1.2. Co jest kontekstem wywołania funkcji greet() ?
var person = {
name: "Jay",
greet: function () {
console.log("hello, " + this.name);
}
};
function greet() {
console.log("hello, " + this.name);
}
// person.greet();
// 2.Co będzie wynikiem wywołania metody greet() ?
// const greet = person.greet;
// greet();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TIP
Wartość this nie jest określana przez miejsce, w którym się znajduje, lecz przez sposób w jaki jest wykonywana.
# 2. Where this is
/* eslint-disable */
// 1. Co będzie wynikiem wywołania poniszego kodu ?
var name = "Jay Global";
var person = {
name: "Jay Person",
details: {
name: "Jay Details",
print: function () {
return this.name;
}
},
print: function () {
return this.name;
}
};
// console.log(person.details.print()); // ??
// console.log(person.print()); // ??
var name1 = person.print;
var name2 = person.details;
// console.log(name1()); // ??
// console.log(name2.print()); // ??
// 2. Co będzie wynikiem wywołania poniŻszego kodu ?
// var car = {
// brand: "Nissan",
// getBrand: function () {
// console.log(this.brand);
// }
// };
// var getCarBrand = car.getBrand;
// getCarBrand();
// 3. Co bedzie wynikiem wywolania poniszego kodu ?
// const call = {
// caller: "mom",
// says: function () {
// console.log(`Hey, ${this.caller} just called.`);
// }
// };
// call.says();
///////////////
// const call = {
// caller: "mom",
// says: () => {
// console.log(`Hey, ${this.caller} just called.`);
// }
// };
// call.says();
///////////////
// const call = {
// caller: "mom",
// says: function () {
// console.log(`Hey, ${this.caller} just called.`);
// }
// };
// let newCall = call.says;
// newCall();
///////////////
// function anotherCaller() {
// console.log(`${this.caller} called, too!`);
// }
// const call = {
// caller: "mom",
// anotherCaller,
// says: function () {
// console.log(`Hey, ${this.caller} just called.`);
// }
// };
// const newCall = call.anotherCaller;
// newCall();
//
// https://dev.to/liaowow/take-this-quiz-understand-how-this-works-in-javascript-44dj
// https://www.sitepoint.com/mastering-javascripts-this-keyword/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 3. Arrow functions
// Co bedzie wynikiem wykonania poniszego kodu ?
// 1. Na co wskazuje ponizszy this ?
// const myFunction = () => {
// console.log(this);
// };
// myFunction();
// 2. Na co wskazuje ponizszy this ?
// const myObject = {
// myMethod: () => {
// console.log(this);
// }
// };
// myObject.myMethod();
// 3. Na co wskazuje ponizszy this ?
// function Car() {
// console.log(this);
// }
// let car = new Car();
// 4.
// function Car() {
// this.speed = 0;
// this.speedUp = function (speed) {
// setTimeout(() => console.log(this.speed + speed), 1000);
// };
// }
// let car = new Car();
// car.speedUp(50); // 50;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
TIP
this wewnatrz funkcji strzalkowej wskazuje zawsze na "lexical scope"
# 4. Use strict
// 1. Jak use strict wplywa na this ?
// (function () {
// "use strict";
// console.log(this);
// })();
// (function () {
// // Without strict mode
// console.log(this);
// })();
// 2. Co bedzie wynikiem wywołania kodu z wiersza 21 ?
// (function () {
// "use strict";
// var item = {
// document: "My document",
// getDoc: function () {
// return this.document;
// }
// };
// var getDoc = item.getDoc;
// console.log(getDoc());
// })();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TIP
use strict chroni nas od niepozadanych operacji na obiekcie window.
# 5. onClick
function clickMe() {
console.log(this);
}
// 1. czym bedzie this ?
// document
// .getElementById("example-button")
// .addEventListener("click", function () {
// console.log(this);
// });
// 2. czym bedzie this ?
// document.getElementById("example-button").addEventListener("click", () => {
// console.log(this);
// });
// 2.1 Jak zapewnic sobie element, kiedy nie mamy kontekstu ?
// document.getElementById("example-button").addEventListener("click", (event) => {
// console.log(event.currentTarget);
// });
var car = {
brand: "Nissan",
getBrand: function () {
console.log(this.brand);
}
};
// document
// .getElementById("example-button")
// .addEventListener("click", car.getBrand);
// Wrocmy tutaj po bind/apply/call
// 3.Przekaz inny obiekt w momencie wywolania eventu click
// document.getElementById("example-button").addEventListener("click", clickMe);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 6. use Bind
TIP
metoda bind pozwala nam na utworzenie metody oraz przypisaniu do niej nowego kontekstu
// 1. Co bedzie wynikiem wykonania się wiersza 10?
// var bobObj = {
// name: "Bob"
// };
// function print() {
// return this.name;
// }
// console.log(print());
// 1.2 Napraw powyższą metode print
// 1.3 Co bedzie wynikiem wywolania ?
// var car = {
// brand: "Nissan",
// getBrand: function () {
// var closure = function () {
// console.log(this.brand);
// };
// return closure();
// }
// };
// car.getBrand();
// 2. Utwórz metodę, która wywoła obj2.printSecondData na zestawie danych z obj1
// poprawny wynik powinien być równy === 2
// var obj1 = {
// data: [1, 2, 3],
// printFirstData: function () {
// if (this.data.length) return this.data[0];
// }
// };
// var obj2 = {
// data: [4, 5, 6],
// printSecondData: function () {
// if (this.data.length > 1) return this.data[1];
// }
// };
// 3.Zmodyfikuj tak funkcję double aby wiersz 34 poprawnie wskazywał na zawartość obiektu "object"
// var object = {
// data: [1, 2, 3],
// double: function () {
// this.data.forEach(function () {
// // Get this to point to object.
// console.log(this);
// });
// }
// };
// object.double();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 7. use Apply
TIP
metoda apply równiez pozwala nam na przypisanie kontesktu do metody z tą różnicą, że apply automatycznie wykona tę metodę
// 1. Wywolaj metodę bark w taki sposób aby przekazać do niej poprawne name
// function Dog(name) {
// this.name = name;
// }
// Dog.prototype.bark = function () {
// console.log(this.name + " says woof");
// };
// const fido = new Dog("fido");
// 2. Meta Math.min zwraca najmniejszą z podanych koljeno liczb jako argumenty - nie mozna przekazać tablicy - mozemy to naprawic za pomoca apply
2
3
4
5
6
7
8
9
10
11
12
13
# 8. use Call
// 1. Jaki będzie wynik wywołania fuynkcji sayName ?
// let dog = {
// name: "doggo",
// sayName() {
// console.log(this.name);
// }
// };
// let sayName = dog.sayName;
// sayName();
// 2. Co będzie wynikiem wywołania następującej funkcji ?
// function convertArgs() {
// return Array.prototype.slice.call(arguments);
// }
// console.log(convertArgs(1, 2, 3, 4, 5, 6));
// 3. document.querySelector() przyjmuje selektor css jako parametr i zwraca listę elementów typu NodeList - co nie czyni jej tablicą - jest to Array-like objects - co znaczy, ze wyglada jak tablica, ale nią nie jest - nie posiada funkcji typowych dla tablic np. includes.
// Napiszmy metodę, która przyjmie jako parametr selektor css i zwróci elementy w postaci tablicy
// console.log(document.querySelectorAll("li"));
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 9. Person Class
To jest trochę tricky - rozkmiń dlaczego 😉
// Co będzie wynikiem wywolania wiersza 17 oraz 18 ?
function Person(name, age) {
this.name = name || "John";
this.age = age || 24;
this.displayName = function () {
console.log(this.name);
};
}
Person.prototype.name = "John";
Person.displayName = function () {
console.log(this.name);
};
var person1 = new Person("Piotr");
person1.displayName();
Person.displayName();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18