JavaScript - this指向详解

84 阅读2分钟

什么是this

在JavaScript中,this是一个关键字,它代表函数运行时,自动生成的一个内部对象。随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是调用函数的那个对象

this的多种绑定规则

1. 默认绑定规则

当函数被调用时,函数中this就会触发默认绑定规则。函数在哪个词法作用域里生效,this 就指向哪里,又因为函数内部没有词法作用域,所以this会一路向外寻找,最后指向全局对象,我们可以通过下列例子来解释清楚.

function Fa() {
  var a = 2;
  this.Fb();
}

function Fb() {
  console.log(this.a);
}
Fa();

在上面代码中我们定义了一个Fa函数,一个Fb函数。Fah函数在全局中被调用,所以Fa函数中的this指向了全局对象。Fb在Fa函数中被调用,this本应指向Fa,但是函数内部没有词法作用域,所以this就往外找,指向了全局。6所以,我们称如果触发了默认绑定规则,那么this就是指向全局对象。

2. 隐式绑定规则

当函数被一个对象所拥有,再调用时,this 会指向该对象。 举个例子,在下面代码中我们定义了一个对象和一个函数。函数作为对象中key为fun键值对的value值。最后我们在第9行通过obj.fun调用这个函数。所以foo函数中的 this指向obj对象

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

var obj = {
     a: 'hello',
     fun: foo
}
obj.fun(); // this指向obj

在函数被多个对象链式调用时,就会触发隐式丢失,此时this就会指向引用函数的对象。

function foo() {
  console.log(this.a);//this指向obj
}

var obj = {
  a: 'hello',
  foo: foo,
};
var obj2 = {
  a: 'world',
  obj: obj,
};
obj2.obj.foo();//隐式丢失

3. 显示绑定规则

显式地使用 call,apply,bind 方法,this 会指向指定对象。 1.call()

function foo(n, m) {
  console.log(this.a, n, m);
}
var obj = {
  a:'obj' ,
};
// foo 的this显示绑定到obj上
foo.call(obj, 'hello', 'world');

2.apply()

function foo(n, m) {
  console.log(this.a, n, m);
}
var obj = {
  a: 'obj',
};
// foo 的this显示绑定到obj上
foo.apply(obj, ['hello', 'world']);//apply中有两个参数一个是绑定的对象,一个是数组里面装着要传入的值

3.bind()

function foo(n, m) {
  console.log(this.a, n, m);
}
var obj = {
  a: 'obj',
};
// foo 的this显示绑定到obj上
var bar = foo.bind(obj)();//bind的执行会返回一个函数体,必须要再次调用才能执行掉
bar('hello', 'world');

4. 箭头函数

箭头函数是 ES6 新增的一种函数表达式,它没有自己的 this,arguments,super,new.target,和原型链等属性,箭头函数的 this 是由外层作用域的 this 决定的。

var obj = {
  name: "张三",
  sayName: function sayName() {
    var foo = () => {
      console.log(this.name);//由于箭头函数没有this,它的this是外层function的this
    };
    foo();
  },
};
obj.sayName();