Detailed explanation of this in JavaScript

高洛峰
Release: 2016-11-28 13:59:24
Original
995 people have browsed it

This in JavaScript is always confusing and should be one of the well-known pitfalls of js. Personally, I also think that this in js is not a good design. Due to the late binding feature of this, it can be the global object, the current object, or... some people even do not use this because of the big pitfalls.


In fact, if you fully grasp the working principle of this, you will naturally not fall into these pits. Let’s take a look at what this will point to in the following situations:

1. this in the global code
1 alert(x);
// The value of global variable x is 2


this in the global scope will Will point to the global object, which is window in the browser.

2. Call as a simple function
function fooCoder(x) {
this.x = x;
}
fooCoder(2);
alert(x);
// The value of global variable x is 2


Here this points to the global object, which is window. In strict mode, it is undefined.

3. Call as method of object
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
console.log(this.name + " says " + sth);
}
}
person.hello("hello world");

output foocoder says hello world. this points to the person object, which is the current object.

4. As a constructor

1 new FooCoder();

this inside the function points to the newly created object.


5. Internal function
var name = "clever coder";

var person = {
name : "foocoder",
hello : function(sth){
var sayhello = function(sth) {
console.log (this.name + " says " + sth);
};
sayhello(
}

person.hello("hello world");
//clever coder says hello world


In the inner function, This is not bound to the outer function object as expected, but to the global object. This is generally considered a design error in the JavaScript language, because no one wants this in the inner function to point to the global object. The way is to save this as a variable, generally agreed as that or self:
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
var that = this ;
var sayhello = function(sth) {
console.log(that.name + " says " + sth);
};
sayhello(sth);
}
}
person.hello("hello world");
//foocoder says hello world


6. Use call and apply to set this

1 person.hello.call(person, "world");

apply is similar to call, except that the following parameters are passed through a The array is passed in instead of separately. The method definitions of the two are:

call(thisArg [, arg1, arg2,...]);
//Parameter list, arg1, arg2,...


apply(thisArg [, argArray] );
// Parameter array, argArray


Both are used to bind a function to a specific object. Naturally, this will be explicitly set to the first Parameters.

A brief summary

To simply summarize the above points, we can find that only the sixth point is confusing.

In fact, it can be summarized as the following points:

When a function is used as an object method. When called, this points to the object.
When the function is called as a fadeout function, this points to the global object (undefined in strict mode)
This in the constructor points to the newly created object
This in nested functions is not inherited The this of the upper-level function, if necessary, can be used to save the this of the upper-level function in a variable.


To summarize simply, if this is used in a function, this will point to the object only when the function is directly called by an object.
obj.foocoder();
foocoder.call(obj, ...);
foocoder.apply(obj, ...);

Go further

We may often write code like this:

1 $ ("#some-ele").click = obj.handler;

If this is used in handler, will this be bound to obj? Obviously not. After the assignment, the function is executed in the callback, and this will be bound to the $("#some-div") element. This requires understanding the execution environment of the function. This article does not intend to go into detail about the execution environment of the function. You can refer to the relevant introduction to the execution environment and scope chain in "Javascript Advanced Programming". What I want to point out here is that understanding the execution environment of the js function will help you better understand this.


So how can we solve the problem of callback function binding? A new method was introduced in ES5, bind():
fun.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg

When the binding function is called, the The parameter will be used as the this point of the original function when running. When the new operator is used to call the bound function, the parameter is invalid.

1 arg1, arg2, ...

When the bound function is called, these parameters are added The parameters of the bound function itself will be used as the parameters of the original function when running in order.


This method creates a new function, called a binding function. The binding function will use the first parameter passed into the bind method when creating it as this, and the second and subsequent parameters passed into the bind method plus the binding When the function is running, the parameters of the function itself are used as parameters of the original function in order to call the original function.

Obviously the bind method can solve the above problem well.
1
2 $("#some-ele").click(person.hello.bind(person));
//When the corresponding element is clicked, the output foocoder says hello world


In fact, this method is also very simple Easy to simulate, let’s take a look at the source code of the bind method in Prototype.js:
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift ();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template