This in JavaScript
This — keywords easy to make headache the programmers js.
When we first learn, this is also quite simple and harmless. If you’ve ever learned Java or C #, you must remember this keyword is used to point to the object that calls the function. In javascript, this keyword plays a similar role. In the code below, we will see that this returns the object person and prints out exactly what we want.
var person = {
firstName: 'Hoang',
lastName: 'Pham',
showName: function () {
console.log (this.firstName + '' + this.lastName);
}
};
// Serialize will lose the method, only keep the properties
JSON.stringify (person); // '{"firstName": "John", "lastName": "Wick"}'
var jsonString = '{"firstName": "John", "lastName": "Wick"}';
var psn = JSON.parse (jsonString); // Convert string to object
console.log (psn.firstName); // John
console.log (psn.lastName); // Wick
In another case, when we declare global variables and global functions, all the variables and functions will be in an object called a window. When we call the function showName, the object window itself is the object that calls that function; this points to the window object itself.
var firstName = 'John', lastName = 'Wick';
// These 2 variables are in the object window
function showName ()
{
console.log (this.firstName + '' + this.lastName);
}
window.showName (); // John Wick. this points to the object window
showName (); // John Wick. The object calling showName is still the object window
And here is the problem
If only used in the two ways above, this is quite easy to understand and does not cause much trouble to use. However, the scary and annoying this will gradually reveal through the following examples. Please continue to read the lesson attentively, don’t watch your ass and your ass;).
Problem 1 — The function is passed as a callback
We want to suppose that when the user clicks on a button, we call the user’s showName function. It’s effortless; pass the showName function as a callback to the click function.
var person = {
firstName: 'John',
lastName: 'Wick',
showName: function () {
console.log (this.firstName + '' + this.lastName);
}
};
// Here this will be the object person
person.showName (); // John Wick.
$ ('button'). click (person.showName); // showName passed as callback
However, the function does not work as expected. Open the developer tools and see that this object has no firstName and lastName fields. Check a little more carefully; we see this here is the button we clicked on, not the object person as in the above example.
In this case, we can correct the error by using an anonymous function or use the bind function to determine if this parameter is passed to the passed function.
Problem 2 — Using this in an anonymous function
Suppose, object person has a friends list; you want to write a function show all friends. In theory, we would write the following:
var person = {
firstName: 'John',
lastName: 'Wick',
showName: function () {
console.log (this.firstName + '' + this.lastName);
}
};
$ ('button'). click (person.showName); // showName is passed as callback, here this is the button
// Use an anonymous function
$ ('button'). click (function () {person.showName ()});
// Use bind
$ ('button'). click (person.showName.bind (person)); // this is still the object personvar person = {
firstName: 'John',
lastName: 'Wick',
friends: ['John', 'Peter', 'Mina', 'Jack'],
showFriend: function () {
for (var i = 0; i <this.friends.length; i ++)
console.log (this.firstName + 'have a friend named' + this.friends [i]);
},
showFriendThis: function () {
this.friends.forEach (function (fr) {
console.log (this.firstName + 'have a friend named' + fr);
});
}
};
person.showFriend (); // The function runs correctly
person.showFriendThis (); // The function is wrong
With the showFriend function, when we use the for function normally, the function runs as expected. However, in the following case, when we use the forEach function, passing an anonymous function, this here becomes an object window, so the firstName field is undefined.
In this case, we use the workaround to create a variable to assign this value and access it in the anonymous function.
var person = {
firstName: 'John',
lastName: 'Wick',
friends: ['John', 'Peter', 'Mina', 'Jack'],
showFriendFixed: function () {
var personObj = this; // Assign this value to the personObj variable
this.friends.forEach (function (fr) {
console.log(personObj.firstName + ' have a friend named ' + fr);
});
}
};
person.showFriendFixed(); //right
Problem 3 — When the function is assigned to a variable
This is a rare case, but I also have the full range. That is the case when we assign a function to a variable, then call that function. The function will not run as expected because the object calling the function is now the object window.
var person = {
firstName: 'John',
lastName: 'Wick',
showName: function () {
console.log (this.firstName + '' + this.lastName);
}
};
// Here this will be the object person, run correctly
person.showName ();
var showNameFunc = person.showName; // Assign the function to the variable showNameFunc
showNameFunc (); // Run wrong, here this will be the object window
To solve this, we also use the bind function as the top case, too simple.
var person = {
firstName: 'John',
lastName: 'Wick',
showName: function () {
console.log (this.firstName + '' + this.lastName);
}
};
// Here this will be the object person, run correctly
person.showName ();
var showNameFunc = person.showName; // Assign the function to the variable showNameFunc
showNameFunc (); // Run wrong, here this will be the object window
In the article, I used the bind function to solve some problems with this keyword. In fact, related to the ass (this) binds and two other beauties as complicated as apply and call.