Study the This in JavaScript

Source: Internet
Author: User

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;

bindTry 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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.