【JS】this指向规则

670 阅读1分钟

默认绑定

// 适用场合:默认情况下
// 指向规则:非严格模式下this指向全局对象,严格模式下this指向undefined
var a = "a";
function foo() {
  console.log(this.a);
}
foo(); // "a"(非严格模式下)

隐式绑定

// 适用场合:调用函数时,有上下文对象
// 指向规则:this指向调用链中的最后一层,即函数的直接调用者
var a = "a",
  obj1 = { a: "a1", foo },
  obj2 = { a: "a2", obj1, foo };
function foo() {
  console.log(this.a);
}
obj1.foo(); // 'a1'
obj2.foo(); // 'a2'
obj2.obj1.foo(); // 'a1'

// 在下面的例子中,虽然bar指向obj1.obj2.foo
// 但在实际调用bar时,未带任何上下文对象
// 所以会导致隐式丢失,并应用默认绑定
var bar = obj2.obj1.foo;
bar(); // 'a'(非严格模式下)

显式绑定

// 适用场合:通过call、bind、bind手动改变了this指向时
// 指向规则:this指向call、apply、bind的第一个参数
var a = "global_a",
  b = "global_b",
  obj = {
    a: "obj_a",
    b: "obj_b",
  };
function foo(a, b) {
  console.log(this.a, this.b, a, b);
}
foo(a, b); // undefined, undefined, global_a, global_b
foo.call(obj, a, b); // obj_a, obj_b, global_a, global_b
foo.apply(obj, [a, b]); // obj_a, obj_b, global_a, global_b
const fooBind = foo.bind(obj);
fooBind(a, b); // obj_a, obj_b, global_a, global_b

new 绑定

// 适用场合:使用new和构造函数创建实例时
// 指向规则:构造函数内的this指向被创建实例
function foo(a) {
  this.a = a;
}
var obj = new foo("a"),
console.log(obj.a); // 'a'

箭头函数

// 适用场合:使用箭头函数时
// 指向规则:箭头函数内的this指向定义箭头函数所处环境中的this,即箭头函数外层的this
// 注意,箭头函数内的this指向不能被call、apply、bind等改变
var a = "a",
  obj = {
    a: "obj",
    foo: function () {
      console.log(this.a);
      (() => {
        console.log(this.a);
      })();
    },
    bar: () => {
      console.log(this.a);
    },
  };
obj.foo(); // 'obj', 'obj'
obj.bar(); // 'a'(非严格模式下)