this的指向问题

8 阅读2分钟

参考链接:juejin.cn/post/737769…

1、函数的独立调用,触发的是默认绑定规则,该函数的this指向window/global(Node.js)。

let a = 1; 
// let/const声明的全局变量,不会挂载到全局对象window上,目的是解决var的全局变量污染问题
console.log(this); 
// Window {window: Window, self: Window, document: document, name: '', location: Location, …}
console.log(this.a); // undefined
var b = 3;
console.log(this.b); // 3
function foo() {
  let a = 2;
  var b = 4;
  console.log(this); 
  // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
  console.log(this.a); // undefined
  console.log(this.b); // 3
}
foo();

2、函数被某个对象所拥有,或者函数被某个上下文对象调用时,触发隐式绑定规则,该函数中的this指向该上下文对象。

let obj1 = {
  a: 1,
  foo: foo1,
};
function foo1() {
  console.log(this); // {a: 1, foo: ƒ}
  console.log(this.a); // 1
}
obj1.foo();

var obj2 = {
  a: 2,
  foo: foo2,
};
function foo2() {
  console.log(this); // {a: 2, foo: ƒ}
  console.log(this.a); // 2
}
obj2.foo();

下面的情况有所不同,这是将函数调用返回的结果赋值给foo,然后访问对象的属性foo,此时foo并不是一个函数。在非严格模式下,this指向了全局

var a = 1;
let obj = {
    a: 2,
    foo: foo(),
};
function foo() {
    console.log(this.a); // 1
}
obj.foo;

3、函数被多个对象链式调用时,this指向最近的那个对象(隐式丢失)

function foo() {
    console.log(this.a); // 1
}

var obj = {
    a: 1,
    foo: foo,
};
var obj2 = {
    a: 2,
    obj: obj,
};
obj2.obj.foo();

4、箭头函数:箭头函数不绑定自己的this,它会捕获其所在上下文的this值作为自己的this值。这意味着在箭头函数中,this的值是在定义函数时确定的,而非调用时。

  var obj = {
    a: 1,
    foo: function () {
      //this
      const fn = () => {
        console.log(this.a); // 1
      };
      fn();
    },
  };
  obj.foo();

5、显示绑定:通过call,apply,bind方法,将函数的this“强行掰弯”到一个对象中。

  var obj = {
    a: 2,
  };
  function foo() {
    console.log(this.a); // 2
  }
  foo.call(obj);

6、new绑定:this指向实例对象

function Person(){
//new的实现过程
  // let obj ={
  //     name:'平平'
  // }
  // Person.call(obj)
  // // obj_proto_ = Person.prototype
  // return obj
  this.name ='平平'
  return 'hello'
}
let p = new Person() //{name:'平平'}
console.log(p.name); // 平平