-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy paththis.js
More file actions
280 lines (217 loc) · 9.01 KB
/
Copy paththis.js
File metadata and controls
280 lines (217 loc) · 9.01 KB
1
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/////important
//////////arrow functions doesn't need to be binded
// https://www.codementor.io/dariogarciamoya/understanding-this-in-javascript-with-arrow-functions-gcpjwfyuc
var person = {
firstName: "Penelope",
lastName: "Barrymore",
fullName: function () {
// Notice we use "this" just as we used "he" in the example sentence earlier?:
console.log(this.firstName + " " + this.lastName); // We could have also written this:
console.log(person.firstName + " " + person.lastName);
}
}
//the this property— is a variable with the value of the object that invokes the function where this is used.
/*
The this reference ALWAYS refers to (and holds the value of) an object—a singular object
and it is usually used inside a function or a method,
although it can be used outside a function in the global scope.
Note that when we use strict mode, this holds the value of undefined in global functions
and in anonymous functions that are not bound to any object.
*/
// A very common piece of jQuery code
$("button").click(function (event) {
// $(this) will have the value of the button ($("button")) object
// because the button object invokes the click () method
console.log($(this).prop("name"));
});
/*
I shall expound on the preceding jQuery example:
The use of $(this), which is jQuery’s syntax for the this keyword in JavaScript,
is used inside an anonymous function, and the anonymous function is executed in the button’s click () method.
The reason $(this) is bound to the button object is because the jQuery library binds $(this) to the object
that invokes the click method. Therefore, $(this) will have the value of the jQuery button ($(“button”)) object,
even though $(this) is defined inside an anonymous function that cannot itself access the “this” variable on the outer function.
Note that the button is a DOM element on the HTML page, and it is also an object;
in this case it is a jQuery object because we wrapped it in the jQuery $() function.
*/
/**
*
* When this is most misunderstood and becomes tricky
The this keyword is most misunderstood when
1- we borrow a method that uses this,
2- when we assign a method that uses this to a variable,
3- when a function that uses this is passed as a callback function,
4- when this is used inside a closure—an inner function.
*/
////////////////////////////////////////////1 borrowing a method ///////////////////////////////
var person = {
firstName: "Penelope",
lastName: "Barrymore",
showFullName: function () {
// The "context"
console.log(this.firstName + " " + this.lastName);
}
}
// The "context", when invoking showFullName, is the person object, when we invoke the showFullName () method on the person object.
// And the use of "this" inside the showFullName() method has the value of the person object,
person.showFullName(); // Penelope Barrymore
// If we invoke showFullName with a different object:
var anotherPerson = {
firstName: "Rohit",
lastName: "Khan"
};
// We can use the apply method to set the "this" value explicitly—more on the apply () method later.
// "this" gets the value of whichever object invokes the "this" Function, hence:
person.showFullName.apply(anotherPerson); // Rohit Khan
// So the context is now anotherPerson because anotherPerson invoked the person.showFullName () method by virtue of using the apply () method
/////////////////////////////////2////////////////////////////////
// We have a simple object with a clickHandler method that we want to use when a button on the page is clicked
var user = {
data: [{
name: "T. Woods",
age: 37
},
{
name: "P. Mickelson",
age: 43
}
],
clickHandler: function (event) {
var randomNum = ((Math.random() * 2 | 0) + 1) - 1; // random number between 0 and 1
// This line is printing a random person's name and age from the data array
console.log(this.data[randomNum].name + " " + this.data[randomNum].age);
}
}
// The button is wrapped inside a jQuery $ wrapper, so it is now a jQuery object
// And the output will be undefined because there is no data property on the button object
$("button").click(user.clickHandler); // Cannot read property '0' of undefined //we have to bind it, since we are passing the function
//solution
$("button").click(user.clickHandler.bind(user));
////////////////////////Fix this inside closure//////////////////
var user = {
tournament: "The Masters",
data: [{
name: "T. Woods",
age: 37
},
{
name: "P. Mickelson",
age: 43
}
],
clickHandler: function () {
// the use of this.data here is fine, because "this" refers to the user object, and data is a property on the user object.
this.data.forEach(
//anonymous functions can't access outerfunctions this
//we can make a local variable for the outer function and let that = this; and use that in the anonymous function
function (person) {
// But here inside the anonymous function (that we pass to the forEach method),
// "this" no longer refers to the user object.
// This inner function cannot access the outer function's "this"
console.log("What is This referring to? " + this); //[object Window]
console.log(person.name + " is playing at " + this.tournament);
// T. Woods is playing at undefined
// P. Mickelson is playing at undefined
})
}
}
user.clickHandler(); // What is "this" referring to? [object Window]
///solution
var user = {
tournament: "The Masters",
data: [{
name: "T. Woods",
age: 37
},
{
name: "P. Mickelson",
age: 43
}
],
clickHandler: function (event) {
// To capture the value of "this" when it refers to the user object, we have to set it to another variable here:
// We set the value of "this" to theUserObj variable, so we can use it later
var theUserObj = this;
this.data.forEach(function (person) {
// Instead of using this.tournament, we now use theUserObj.tournament
console.log(person.name + " is playing at " + theUserObj.tournament);
})
}
}
user.clickHandler();
// T. Woods is playing at The Masters
// P. Mickelson is playing at The Master
///////////////////////////////////////////Fix this when method is assigned to a variable
// This data variable is a global variable
var data = [{
name: "Samantha",
age: 12
},
{
name: "Alexis",
age: 14
}
];
var user = {
// this data variable is a property on the user object
data: [{
name: "T. Woods",
age: 37
},
{
name: "P. Mickelson",
age: 43
}
],
showData: function (event) {
var randomNum = ((Math.random() * 2 | 0) + 1) - 1; // random number between 0 and 1
// This line is adding a random person from the data array to the text field
console.log(this.data[randomNum].name + " " + this.data[randomNum].age);
}
}
// Assign the user.showData to a variable
var showUserData = user.showData;
// When we execute the showUserData function, the values printed to the console are from the global data array,
// not from the data array in the user object
//
showUserData(); // Samantha 12 (from the global data array)
// Solution for maintaining this when method is assigned to a variable:
// We can fix this problem by specifically setting the this value with the bind method:
// Bind the showData method to the user object
var showUserData = user.showData.bind(user);
// Now we get the value from the user object, because the this keyword is bound to the user object
showUserData(); // P. Mickelson 43
function IsReversed(name) {
let nameReversed = name.split('').reverse().join('');
return name === nameReversed;
}
/////fuckedup this
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function (fn) {
fn(); //10 window.length
arguments[0](); //2 arguments.length
}
};
obj.method(fn, 1);
//////////////////////arrow functions doesn't rebind this
let person = {
talks() {
console.log(this); //person object
setTimeout(function () {
console.log(this); //window object
}, 1000);
}
}
let person = {
talks() {
console.log(this); //person object
setTimeout(() => {
console.log(this); //person object, it will inherit the scope of the context it was written at
}, 1000);
}
}