In JS, this is the context in which it is directed according to its scope.
Global execution
In the global context, let's see what it is:
You can see that a Window object is returned.
In node, this returns the global object.
Summary : It executes the current global object in the global scope this
(browser side is Window
, node is global
).
function to execute the
Purely function calls
As we can see, when a function is called directly, it belongs to the global call, when it points to the global object.
Strict mode ' use strict ';
If you perform a purely function call in strict mode, this does not point to the this
global, but instead undefined
, it is done to eliminate some of the non-rigorous behavior of JS:
In the console, print out the undefined.
Of course, it would be better to put it in an immediate execution function, avoiding the overall pollution:
Method invocation as an object
When a function is invoked as a method of an object:
At this point, this points to the current object,
Of course, we can still do this,
Same constant, because JS in everything object, function is also an object, for test, it is just a function name, function reference, it points to this function, when Foo=test, Foo also points to this function.
If the object's method is assigned to a variable, then the variable is called directly:
You can see that at this
this time the global is executed, and when we put it test = obj.foo
directly to test
a reference to a function, obj
it is not actually related to this object, so it is used as a normal function to call directly, so, point to the this
global object.
Some pits
We often encounter some pits in the callback function:
var obj = { name:' Holy ', foo:function() { Console.log ( This ); }, foo2:function() { Console.log (this); SetTimeout (this. foo,1000); } ; Obj.foo2 ();
View Code
After executing this code, we will find that two times the print out of this is not the same.
For the first time, this is printed directly in Foo2, which points to the Obj object, where we have no doubt;
But This.foo, which executes in settimeout, points to the global object, does this not use it as a function method? This makes many beginners very puzzled.
In fact, SetTimeout is a method of global objects, Window.settimeout () abbreviated to SetTimeout ();
Moreover, settimeout is just a function, the function must have the parameter, we put This.foo as a parameter to settimeout this function, as it needs a fun parameter, in the passing of parameters, actually did a such operation, fun = This.foo, see, here we direct the fun point to the This.foo reference; execution is actually a fun () so it's not related to obj, it's called directly as a normal function, so this is pointing to the global object.
This problem is commonly encountered in many asynchronous callback functions;
Solve
In order to solve this problem, we can use the characteristics of closures to deal with;
varobj ={name:' Holy ', foo:function() {Console.log ( This); }, Foo2:function() {Console.log ( This); var_this = This; SetTimeout (function() {Console.log ( This, _this); },1000); } }; Obj.foo2 ();
View Code
You can see that this is still window, because this in Foo2 is pointing to obj, we can store it with a variable _this first, and then use _this in the callback function to point to the current object;
Another pit of settimeout.
As previously mentioned, if you execute the callback function directly without the binding scope, then its this is pointing to the Global Object (window), in strict mode will point to undefined, but in the setTimeout of the callback function in strict mode, but the performance is different;
Supposedly, we added strict mode, Foo call did not specify this, should be out of the undefined, but there is still a global object, is the strict mode failure?
Not, even in strict mode, when the SetTimeout method calls an incoming function, if the function has no specified this, then it does an implicit operation---an automatic injection of the global context, equivalent to calling
foo.apply (window) rather than foo ();
Of course, if we have specified this when we pass in the function, it will not be injected into the global object for a long time, such as
SetTimeout (Foo.bind (obj), 1);
Please refer to this article.
Use as a constructor
In JS, in order to implement the class, we need to define some constructors, when calling a constructor, we need to add the new keyword;
We can see that this is the object that is instantiated when the constructor is called when the call is constructed, and of course, the constructor is actually a function, and if we execute it as a normal function, this one still performs the global;
Arrow functions
In ES6 's heart specification, the arrow function is added, and it is the point of this which is the most different from the normal function.
var obj = { ' QIUTC ', function() { Console.log (this ); }, function() { Console.log (this); = = { Console.log (this); // Object {name: "QIUTC"} }, +);} } Obj.foo2 ();
View Code
As you can see, in the setTimeout
function that executes, it should have been printed Window
, but this
pointed here, obj
because the setTimeout
function (parameter) passed in is an arrow function:
The This object in the body of the function is the object that is defined, not the object that is used.
Let's take a look at this sentence by example:
At the obj.foo2()
time of execution, the current this
point of reference obj
; at execution setTimeout
time, we define an anonymous arrow function, the key is here, the arrow function in the this
execution of the definition of the object, is to define the arrow function in the scope of the this
, that obj.foo2
this
is, in the, that is, obj
so in the execution of the arrow function, it's, and so on this
obj.foo2 中的 this
obj
;
Simply put, the this in the arrow function is only relevant to the scope that defines it, not to where and how it is called, while its this point is immutable.
Call, apply, bind
In JS, the function is also an object, there are also some methods, here we introduce three methods, they can change the function of the this
point
- Pager
Fun.call (thisarg[, arg1[, arg2[, ...])
|
It executes the function immediately, the first parameter is the context in the specified execution function this
, and the following argument is the parameter that the function needs to pass in;
- Apply
Fun.apply (thisarg[, [Arg1, Arg2, ...])
|
It executes the function immediately, the first parameter is the context in the specified execution function this
, the second argument is an array, and is the argument to the execution function ( call
the difference);
- Bind
var foo = fun.bind (thisarg[, arg1[, arg2[, ...]);
|
It does not execute the function, but instead returns a new function, the new function is specified by the this
context, and the following arguments are the parameters that the function needs to pass in;
These three functions are actually very similar, the general purpose is to specify a function of the context (this), we take the call
function as an example;
Specify this for a normal function
var obj = { ' QIUTC ' };
Foo () { Console.log (this); }
Foo.call (obj);
Object {name: "QIUTC"}
|
As you can see, in the execution foo.call(obj)
, the function this
points to the obj
object and succeeds;
Specify a this for the methods in the object
var obj = { foo: function ( console.log ( this); var Obj2 = { name: obj.foo.call (OBJ2); //Object {name: "tcqiu222222"} |
As you can see, the execution of the function here this
points to a obj2
success;
Specify this for the constructor function
function person (name) { this.name = name; console.log (this); var obj = { ' qiutc2222222 ' }; var p = new person.call (obj, ' QIUTC '); //uncaught TypeError:Person.call is not a Constructor (...) /span> |
Here's a mistake, because we went to the new
Person.call
function, not the Person
function here is not a constructor;
bind
Try it:
functionPerson (Name) { THIS.name = name; console.log (this); var obj = { ' qiutc2222222 ' }; var Person2 = Person.bind (obj); var p = new Person2 ( ' QIUTC '); //person {name: ' QIUTC '} console.log (obj); //Object {name: "qiutc2222222"} |
The printed object is Person
instantiated, and there is no relationship, and there is obj
obj
no change, stating that we give the Person
specified this
context does not take effect;
Therefore, it can be concluded that using bind to a constructor specifies this
that, at the new
time of this constructor, the bind
function specified this
does not take effect;
Of course bind
not only can you specify this
, but also pass in parameters, let's try this operation:
function person (name) { span class= "keyword" >this.name = name; console.log (this); var obj = { ' qiutc2222222 ' }; var Person2 = Person.bind (obj, ' qiutc111111 '); var p = new Person2 ( Span class= "string" > ' QIUTC '); //person {name: ' qiutc111111 '} |
As you can see, although the designation this
does not work, the incoming parameters still work;
Specify this for the arrow function
Let's define a global arrow function, so the arrow function is bound to point to the this
global object, if the call
method is changed this
:
var afoo = (a) + = { console.log (a); console.log (this); afoo (1); //1 Window var obj = { Name: ' QIUTC ' }; afoo.call (obj, 2); //2 Window |
As you can see, the point here is call
this
not successful, so it can be concluded that the this in the arrow function has been determined at the time it was defined (this in the scope of the definition), unrelated to how and where it was called, including (call, apply, bind ) cannot be changed by this action.
Just remember that the arrow function Dafa is good and unchanging this
.
This article originates from this in JavaScript. Feel good on the turn.
Study the This in JavaScript