This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!

When using JavaScript, many developers are somewhat confused about this, but in fact, remember the most important sentence about this: which object calls the function, and which object this in the function refers to.

Several modes of this:

  1. In method call mode, this always points to the object that called its method. This is related to where the method was called, not where the method was declared (arrow functions are special).
  2. When a function is called, this refers to window. When a method is called without an object, this refers to window, such as setTimeout, anonymous function, etc.
  3. In constructor mode, this refers to the object being constructed;
  4. In the apply,call, and bind mode, this refers to the first argument;
  5. The arrow function, which is bound to this when declared, not depending on where it is called;
  6. In strict mode, this is undefined if it is not defined by the execution context.

Here are some examples and principles for these cases:

1. Method invocation pattern

// Declare the location
var test = function(){
  console.log(this.x)
} 

var x = "2";

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

// Call location
obj.fn(); / / 1

test(); / / 2
Copy the code

So in the code above, you can see that this is pointing to the object that called its method, test is under the obj object, so this is pointing to obj, test is under the window object, so this is pointing to window. You can also see that this has nothing to do with where you declare it, but where you call it.

But here’s the thing to note

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

Fn was assigned from obj2.fn, but it was obj1 that called the function, so this refers 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();
Copy the code

Anonymous function, setTimeout:

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

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

3. Constructor pattern

var flag = undefined; 

function Fn(){
  flag = this;
}    

var obj = new Fn();

console.log(flag === obj); // true
Copy the code

So this is going to refer to obj, and the internal principle is to use apply to refer this to obj, and remember that in JavaScript we have a new object.

4. Call, apply, bind

Call and apply function, exactly the same, the only difference: parameters; The first argument is the reference to this in the function body, and the second argument is passed in sequence. Apply takes two arguments, the first of which is also the reference to this in the function body. The second argument is a collection object (array or array-like)

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
Copy the code

5. Arrow function

The “this” in the “this” function is the context, and the “this” in the “this” function is the context.

Judge arrow function this:

Tip: There is no outside function. This is window; We have a function on the outer layer, and we see who the “this” of the outer function is, and that’s who the “this” is.

The outer function can be a regular function or an arrow function. The outer function this can be determined in different ways depending on the type of function:

The outer function is a regular function depending on who called it;

The outer layer is the arrow function and that’s what I said;

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

A.sayHello(); // The output is window

// Bind A to A forever:

var name = 'window'; 
var A = {
  name: 'A'.sayHello: function(){
    var s = () = > console.log(this.name)
    return s// Return the arrow function s}}var sayHello = A.sayHello();
sayHello();/ / output A
Copy the code
  • The call(), apply(), and bind() methods are passed as arguments to the arrow function and have no effect on this;
  • Given that this is lexical, rules related to this in strict mode are ignored (regardless of whether the effect 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
Copy the code

6. Strict mode

In non-strict mode, this defaults to the global object window;

// Non-strict mode
function f1(){
  return this;
}
console.log(f1() === window); // true
Copy the code

In strict mode, this is undefined;

// Strict mode
"use strict";
var fn2 = function(){
  return this
}    
console.log(fn2() == undefined); // true
Copy the code