1. This points to the constructor instantiation object
In the previous article, we mentioned the difference between using new and not calling constructors, as shown in the following example:
The code copy is as follows:
function Benjamin(username, sex) {
this.username = username;
this.sex = sex;
}
var benjamin = new Benjamin("zuojj", "male");
//Outputs: Benjamin{sex: "male",username: "zuojj"}
console.log(benjamin);
var ben = Benjamin("zhangsan", "female");
//Outputs: undefined
console.log(ben);
When the constructor is called as a normal function, no value is returned, and this points to the global object. So how can we avoid problems caused by the lack of new keywords?
The code copy is as follows:
function Benjamin(username, sex) {
//Check whether "this" is a "Benjamin" object
if(this instanceof Benjamin) {
this.username = username;
this.sex = sex;
}else {
return new Benjamin(username, sex);
}
}
var benjamin = new Benjamin("zuojj", "male");
//Outputs: Benjamin{sex: "male",username: "zuojj"}
console.log(benjamin);
var ben = Benjamin("zhangsan", "female");
//Outputs: Benjamin {username: "zhangsan", sex: "female"}
console.log(ben);
In the above example, we first check whether this is an instance of Benjammin, if not, use new to automatically call the constructor and instantiate it, which means that we no longer need to worry about missing new keyword instantiation constructor. Of course, we may develop a bad habit in this way. What if we avoid this phenomenon? We can throw an error like this:
The code copy is as follows:
function Benjamin(username, sex) {
//Check whether "this" is a "Benjamin" object
if(this instanceof Benjamin) {
this.username = username;
this.sex = sex;
}else {
// If not, throw error.
throw new Error("`Benjamin` invoked without `new`");
}
}
2. This points to the object that calls the function
See the following example:
The code copy is as follows:
var x = 10;
var obj = {
x: 10,
output: function() {
//Outputs: true
console.log(this === obj);
return this.x;
},
innerrobj: {
x: 30,
output: function() {
//Outputs: true
console.log(this === obj.innerobj);
return this.x;
}
}
};
//Outputs: 10
console.log(obj.output());
//Outputs: 30
console.log(obj.innerobj.output());
3. This points to the global object
When discussing the constructor above, we also discussed that when new is not applicable, this will point to the global object. Let’s take a look at two common examples that are prone to errors:
The code copy is as follows:
var x = 100;
var obj = {
x: 10,
output: function() {
(function() {
//Outputs: true
console.log(this === window);
//Outputs: Inner: 100
console.log("Inner:" + this.x);
})();
return this.x;
}
};
//Outputs: 10
console.log(obj.output());
When using closures, the scope changes, and this points to window (in the browser).
The code copy is as follows:
var x = 100;
var obj = {
x: 10,
output: function() {
return this.x;
}
};
var output = obj.output;
//Outputs: 10
console.log(obj.output());
//Outputs: 100
console.log(output());
var obj2 = {
x: 30,
output: obj.output
}
//Outputs: 30
console.log(obj2.output());
At this time this always points to the object at the time of the function call.
4. This points to the object assigned by the apply/call() method
The code copy is as follows:
var x = 100;
var obj = {
x: 10,
output: function() {
return this.x;
}
};
//Outputs: 10
console.log(obj.output());
var obj2 = {
x: 40,
output: obj.output
}
//Outputs: 40
console.log(obj.output.call(obj2));
//Outputs: 10
console.log(obj2.output.apply(obj));
5. This of the callback function points to the object pointed to by this function that calls the callback.
The code copy is as follows:
//<input type="text" value="3" id="txt_username">
$("#username").on("click", function() {
console.log(this.value);
});
6. This in Function.prototype.bind
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
Example 1:
The code copy is as follows:
function person() {
return this.name;
}
//Function.prototype.bind
var per = person.bind({
name: "zuojj"
});
console.log(per);
var obj = {
name: "Ben",
person: person,
per: per
};
//Outputs: Ben, zuojj
console.log(obj.person(), obj.per());
Example 2:
The code copy is as follows:
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
//Outputs: 81
console.log(module.getX());
var getX = module.getX;
//Outputs: 9, because in this case, "this" refers to the global object
console.log(getX);
// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
//Outputs: 81
console.log(boundGetX());