About This pointing problem

1 definition

thisThe keyword is an internal object that is automatically generated while the function is running. The function does not execute,thisThere's no point. Can only be used inside a function, always pointing to the object calling itCopy the code

2 Binding Rules

  • Default binding: The default points to Window, and the standalone calls also point to window
  • The new binding
  • Explicit binding: Call apply bind
  • Implicit binding: the caller points to the caller (special case: implicit loss, parameter assignment)

Example: Default binding

// Define the person function in the global environment, internally using the this keyword
// ** executes the function independently. This refers to window**

var name = 'Jenny';
function person() {
    return this.name;
}
console.log(person());  //Jenny
Copy the code

Example: New binding

// Generate an instance object by building the function new keyword, in which case this refers to the instance object

function test() {
 this.x = 1;
}

var obj = new test();
obj.x / / 1
Copy the code

Special Case 1:

// The new procedure encounters a return object, in which case this refers to the returned object

function fn() {  
  this.user = 'xxx';  
  return {};  
}
var a = new fn();  
console.log(a.user); //undefined
Copy the code

Special Case 2:

// If a simple type is returned, this points to the instance object

function fn() {  
  this.user = 'xxx';  
  return 1;
}
var a = new fn;  
console.log(a.user); //xxx
Copy the code

Special Case 3:

// Note that null is also an object, but new still points to the instance object

function fn() {
  this.user = 'xxx';  
  return null;
}
var a = new fn;  
console.log(a.user); //xxx
Copy the code

Example: Explicit binding

Apply (), call(), and bind() are methods of a function that change the object on which the function is called. Its first argument represents the changed object on which the function was called. So, in this case this refers to the first parameter

var x = 0;
function test() {
 console.log(this.x);
}

var obj = {};
obj.x = 1;
obj.m = test;
obj.m.apply(obj) / / 1
Copy the code
function test(a,b,c,d) {
  console.log(a, b, c, d)
}

const obj = {
  a:2.foo: test
}

var bar = obj.foo
obj.foo(1.2.3.4)
bar.call(obj, 1.2.3.4)
bar.apply(obj, [1.2.3.4])
bar.bind(obj)(1.2.3.4)
Copy the code

Example: Implicit binding

The function can also be used as a method on an object, in which case this refers to the parent object

function test() {
  console.log(this.x)
  function inner() {
    console.log(this)
  }
  inner()
  // Note that inner is a standalone execution and points to the window
}
const obj = {}
obj.x = 1
obj.m = test
obj.m() // 1 window
Copy the code
// The self-executing function refers to the window in any case no matter how it is called
// if in the Node environment points to the corresponding global object

(function foo() {
  console.log(this)  // window}) ()Copy the code
Obj.foo () is equivalent to the test function
// obj.foo()() equals test(), and this refers to the window

const obj = {
  a: 'xxx'.foo: function() {
    function test() {
      console.log(this)}return test()
  }
}
obj.foo()() // window
Copy the code
// The function contains multiple objects. Although the function is called by an outer object, this refers only to the object above it

var o = {
  a: 10.b: {
    fn: function() {
      console.log(this.a)
    }
  }
}
o.b.fn()

// The object above this is b, and b has no definition of a variable, so the structure is undefined
Copy the code

Special Case 1: Variable assignment (implicit loss)

var o = {
    a:10.b: {a:12.fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window}}}var j = o.b.fn;
j();

// This always refers to the object that last called it. This has no meaning if it is not called.
// Although fn is b's method, the assignment of fn to j is not performed, so it ends up pointing to window.
// is a separate call to a function
Copy the code

Special case 2: Parameter assignment

var a = 0
function foo() {
  console.log(this)}function bar(fn) {
  fn()
}
var obj = {
  a: 2.foo: foo
}
// During precompilation, arguments are assigned as parameters (shallow copy of values)
bar(obj.foo)
// bar(obj. Foo) is the function that executes bar, fn is the function that represents foo
// Calling fn() is a separate call to foo, so the window is called
Copy the code

3 priority

Default binding < implicit binding < display binding < new binding

function foo(b) {
  this.a = b
}
var obj1 = {}
var bar = foo.bind(obj1)
bar(2)

console.log(obj1.a) / / 2
var baz = new bar(3)
console.log(obj1.a) / / 2
console.log(baz) / / 3

Copy the code