The This in Javascript

Source: Internet
Author: User
Tags sessionstorage

Executing in the global

Let's see what this is in the global.

first, in the browser :

Console.log (this); // Window {speechsynthesis:speechsynthesis, caches:cachestorage, Localstorage:storage, Sessionstorage:storage, Webkitstorageinfo:deprecatedstorageinfo ...}

Visible, in the browser this point to window

second, in node :

Console.log (this); // Global

In node, this points to global

Summary : It executes the current global object in the global scope (the browser side is global in Window,node).

Executing in a function

Purely function calls

function Test () {  console.log (this//  Window {speechsynthesis: Speechsynthesis, Caches:cachestorage, Localstorage:storage, Sessionstorage:storage, WebkitStorageInfo: Deprecatedstorageinfo ...}

Strict mode ' use strict '
"Use strict" function foo () {    Console.log (this);} Foo (); // undefined

Of course, it would be better to put it in your own execution function using "use strict" to avoid contaminating the global

(Functuon () {    "use strict"    Console.log (this);}) (); // undefined

Method invocation as an object

var obj = {  ' QIUTC ',  function() {    Console.log (this  . Name);   // ' QIUTC '

This time, this point points to the current object;

Of course, we can also do this:

function Test () {  Console.log (this. name);} var obj = {  ' QIUTC ',  //  ' QIUTC '

If you copy the object's methods directly to a variable to which to go, see

var obj = {  ' QIUTC ',  function() {    Console.log (this );   var test =//  Window

As you can see, this points to the window, where test points to a reference to the Obj.foo function, which is irrelevant to the Obj object, and test is a global variable, so test () is called as a normal function, so this is a point to the window.

Some pits

var obj = {  ' QIUTC ',  function() {    Console.log (this  );  },  function() {    Console.log (this);    SetTimeout (this. Foo, +);  }} Obj.foo2 ();

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, which we have no doubt;

But This.foo, which executes in setTimeout, points to the global object, isn't it used as a function method? This often makes many beginners puzzled;
In fact, SetTimeout is just a function, the function is necessarily likely to need parameters, we put This.foo as a parameter to setTimeout this function, as it needs a fun parameter, when passed in the parameters, in fact, did a such operation fun = This.foo, see no, here we direct the fun point to the This.foo reference, the execution of the time is actually executed fun () so it has nothing to do with obj, it is called as a normal function directly, so this point to the global object.

This problem is commonly encountered in many asynchronous callback functions;

Solve

To solve this problem, we can use the characteristics of closures to deal with:

varobj ={name:' QIUTC ', foo:function() {Console.log ( This); }, Foo2:function() {Console.log ( This); var_this = This; SetTimeout (function() {Console.log ( This);//WindowConsole.log (_this); //Object {name: "QIUTC"}}, 1000); }} obj.foo2 ();

Can be seen directly with this is still the Window; because this in foo2 points to obj, we can store it with a variable _this first, then use _this in the callback function to point to the current object;

Another pit of SetTimeout.

Before that, if you execute the callback function directly without the binding scope, then it is pointing to the Global Object (window), and in strict mode it points to undefined, but the callback function in SetTimeout behaves differently in strict mode.

' Use strict 'function  foo () {  Console.log (this1//  window

Supposedly we added strict mode, Foo call also did not specify this, should be out undefined, but here still appear global object, is strict mode invalid?

No, 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-automatically injecting the global context, equivalent to calling foo.apply (window) rather than foo ();

Of course, if we have specified this when passing in the function, then we will not be injected into the global object, for example: SetTimeout (Foo.bind (obj), 1);

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:

function Person (name) {  this. Name= name;  Console.log (this varnew person (' QIUTC '//  person {name: "QIUTC"}

We can see that when called as a constructor, this points to the object instantiated by the constructor call;

Of course, the constructor is actually a function, and if we take it as a normal function, this one still performs the global:

function Person (name) {  this. Name= name;  Console.log (this var p = person (' QIUTC '//  Window

The difference is how the function is called (new).

Arrow functions

In the new specification of ES6, the arrow function is added, which is the most different from the normal function is the point of this, remember in the above (as the object of the method call-some pits-solve) we use closures to solve the problem of this point, if the use of the arrow function can be more perfect solution:

var obj = {  ' QIUTC ',  function() {    Console.log (this  );  },  function() {    Console.log (this);     = = {      Console.log (this);  // Object {name: "QIUTC"}    }, +);}  } Obj.foo2 ();

As you can see, in the function that setTimeout executes, it should have been printed in Window, but here this is pointing to obj, because the function (parameter) passed to SetTimeout 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 time of Obj.foo2 () execution, the current this point points to obj, and in the execution of SetTimeout, we first define an anonymous arrow function, where the key is the object in which this is defined when the this arrow function is defined, which is the scope of the This, which is the this in Obj.foo2, that is, obj; so when the arrow function is executed, it's this------and obj in Obj.foo2;

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 this point:

    • Pager
      Fun.call (thisarg[, arg1[, arg2[, ...])
      It executes the function immediately, the first parameter is the context that specifies the this in the execution function, and the following arguments are the parameters that the function needs to pass in;

    • Apply
      Fun.apply (thisarg[, [Arg1, Arg2, ...])
      It executes the function immediately, the first parameter is the context that specifies the this in the execution function, the second argument is an array, and is the argument to the execution function (the difference from call);

    • Bind
      var foo = fun.bind (thisarg[, arg1[, arg2[, ...]);
      Instead of executing the function, it returns a new function that is assigned the context of this, and the arguments that follow are the parameters that the function needs to pass in;

These three functions are actually quite similar, the general purpose is to specify a function context (this), we take the call function as an example;

Specify this for a normal function
var obj = {  ' qiutc 'function  foo () {  Console.log (this  //  Object {name: "QIUTC"}

As you can see, in the execution of Foo.call (obj), this object in the function points to obj, which is successful;

Specify a this for the methods in the object
var obj = {  ' QIUTC ',  function  () {    Console.log (this );   var obj2 = {  ' tcqiu222222 '//  Object {name: "tcqiu222222"} 

As you can see, this is where the function is executed, which points to the OBJ2, success;

Specify this for the constructor function
function Person (name) {  this. Name= name;  Console.log (thisvar obj = {  ' qiutc2222222 'var New Person.call (obj, ' qiutc '//  uncaught TypeError:Person.call is not a constructor (...)

Here's a mistake because we went to new Person.call function, not person, here is not a constructor function;

Change to bind try:

 function   person (name) { this . Name = name; Console.log ( this   var  obj = {name:  ' qiutc2222222 ' Span style= "COLOR: #000000" >};  var  Person2 = Person.bind (obj);  var  p = new  Person2 (' QIUTC ' );  //  person {name: "QIUTC"}   Console.log (obj);  //  Object {name: "qiutc2222222"}  

The printed object is instantiated by the person, and obj has no relation, and obj has not changed, stating that we have given the person the this context is not in effect;

Therefore, it can be concluded that by using bind to assign this to a constructor, the this specified by the BIND function does not take effect at the time of the new constructor .

Of course bind can not only specify this, but also pass in parameters, let's try this operation:

function Person (name) {  this. Name= name;  Console.log (thisvar obj = {  ' qiutc2222222 'var Person2 = Person.bind (obj, ' qiutc111111 'varnew Person2 (' QIUTC '// person {name: "qiutc111111"}

As you can see, although specifying this does not work, the incoming parameters still work;

Specify this for the arrow function

Let's define a global arrow function, so this one in the arrow function will necessarily point to the global object, and if you change this with the call method:

var afoo = (a) + = {  console.log (a);  Console.log (this);} Afoo (1//  1//  Windowvar obj = {  ' QIUTC '2//  2//  Window

As you can see, the call to this here is 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 where it was defined), regardless of how and where it was called, including (calls, apply, b IND) cannot change its this.

Just remember the arrow function Dafa good, unchanging this.

The This in Javascript

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.