Detailed explanation of this in JavaScript

When using JavaScript to develop, many developers are more or less confused by the point of this, but in fact, about the point of this, remember the most core sentence: which object calls the function, and which object this in the function points to .

Several modes of this:

  1. In method call mode, this always points to the object where the method is called, and the direction of this is related to the calling position of the method, and has nothing to do with the declaration position of the method (arrow functions are special);
  2. Under function call, this points to window. When the calling method does not have a clear object, this points to window, such as setTimeout, anonymous functions, etc.;
  3. In the constructor call mode, this points to the object being constructed;
  4. In apply, call, bind call mode, this points to the first parameter;
  5. Arrow function, bind this at the time of declaration, rather than depending on the call location;
  6. In strict mode, if this is not defined by the execution context, then this is undefined;

Below we give examples and explain the principles for these situations:

1. Method invocation mode

// 声明位置
var test = function(){
    
    
  console.log(this.x)
} 

var x = "2";

var obj = {
    
    
  x:"1",
  fn:test,
}

// 调用位置
obj.fn(); // 1

test(); // 2

In the above code, you can see that this points to the object where it is called, the test method is under the obj object, so this points to obj, and test is under the window object, so this points to window. It can also be seen that this has nothing to do with the position of the declaration, but is related to the position of the call.

But pay attention to the following situation

let obj1={
    
    
  a:222
};
let obj2={
    
    
  a:111,
  fn:function(){
    
    
    console.log(this.a);
  }
}
obj1.fn = obj2.fn;
obj1.fn(); // 222

This is not difficult to understand. Although obj1.fn is assigned from obj2.fn, the calling function is obj1, so this points to obj1.

2. Function call mode

var a = 1;
function fn1(){
    
    
  console.log(this.a); // 1
}
fn1();

window.b = 2;
function fn2(){
    
    
  console.log(this.b); // 2
}
fn2();
//可以理解为 window.fn();

Anonymous function, setTimeout:

(function(){
    
    
  console.log(this); // window
})();

setTimeout(() => {
    
    
  console.log(this); // window
}, 0);

setTimeout(function(){
    
    
  console.log(this); // window
}, 0);

3. Constructor Mode

var flag = undefined; 

function Fn(){
    
    
  flag = this;
}    

var obj = new Fn();

console.log(flag === obj); // true

This this points to obj. The internal principle is to use apply to point this to obj. Recall the detailed explanation of the new object process in JavaScript .

4. call、apply、bind

The functions of call and apply are exactly the same, with the only difference: parameters;
the parameters received by call are not fixed. The first parameter is the point of this in the function body, and the second parameter is the following parameters that are passed in sequentially.
apply receives two parameters, the first parameter is also the point of this in the function body. The second parameter is a collection object (array or class array)

var obj = {
    
    
  name:'111',
  getName:function(){
    
    
    console.log(this.name)
  }
};

var otherObj = {
    
    
  name:'222',
};

var name = '333';
        
obj.getName();               // 111
obj.getName.call();          // 333
obj.getName.call(otherObj);  // 222
obj.getName.apply();         // 333
obj.getName.apply(otherObj); // 222
obj.getName.bind(this)();    // 333
obj.getName.bind(otherObj)();// 222

5. Arrow functions

Regarding the arrow function in ES6, the official explanation is:
the this in the arrow function is the context, and the this in the outer scope is the this in the arrow function.

Judging the this of an arrow function:
Tips: It has no function in the outer layer, this is window; there is a function in the outer layer, depending on who the this of the outer function is and whose this is.
The outer function may be a regular function or an arrow function. Different methods are used to determine the outer this according to the type of function: the
outer function is a regular function, depending on who called the outer function; the
outer function is an arrow function just Say the skills to judge;

let obj={
    
    
  a:222,
  fn:function(){
    
        
    setTimeout(()=>{
    
    console.log(this.a)});
  }
};
obj.fn(); // 222
var name = 'window'; 
var A = {
    
    
  name: 'A',
  sayHello: () => {
    
    
    console.log(this.name)
  }
}

A.sayHello(); // 输出的是window,根据刚才讲的规则就可以判断

// 那如何改造成永远绑定A呢:

var name = 'window'; 
var A = {
    
    
  name: 'A',
  sayHello: function(){
    
    
    var s = () => console.log(this.name)
    return s//返回箭头函数s
  }
}

var sayHello = A.sayHello();
sayHello();// 输出A 
  • The call(), apply() and bind() methods are just passing parameters to the arrow function, and have no effect on its this;
  • Considering that this is at the lexical level, all rules related to this in strict mode will be ignored (ignoring whether it is in strict mode or not);
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true

var obj = {
    
    foo: foo};
console.log(foo.call(obj) === globalObject); // true

foo = foo.bind(obj);
console.log(foo() === globalObject); // true

6. Strict mode

In non-strict mode, this points to the global object window by default;

// 非严格模式
function f1(){
    
    
  return this;
}
console.log(f1() === window); // true

In strict mode, this is undefined;

// 严格模式
"use strict";
var fn2 = function(){
    
    
  return this
}    
console.log(fn2() == undefined); // true

Guess you like

Origin blog.csdn.net/ZYS10000/article/details/112439053