this指向

90 阅读2分钟

一 this总览。

首先我们知道this的指向是在调用函数的时候确定的,(执行上下文知识)。因此,一个函数中的this指向,可以非常灵活。同一个函数调用方式不同,this指向就不同,this的指向可不是静态的哦。 而且在函数内部不能修改this。

如果调用者函数被某一个对象所拥有,那么this指向这个对象,如果调用者函数单独调用那么,this指向undefined。非严格模式this指向全局window。
从结论中我们可以看出,想要准确确定this指向,找到函数的调用者以及区分他是否是独立调用十分关键。 有很多例子:

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

function active(fn) {
  fn(); // 真实调用者,为独立调用
}

var a = 20;
var obj = {
  a: 10,
  getA: foo
}

active(obj.getA);

这个情况输出的是20,全局变量,active()执行的时候this指向全局对象window。

二:改变this指向:call,aplly,bind

一个例子

function Person(name, age) {

    // 这里的this指向了谁?
    this.name = name;
    this.age = age;   
}

Person.prototype.getName = function() {

    // 这里的this又指向了谁?
    return this.name;
}

// 上面的2个this,是同一个吗,他们是否指向了原型对象?

var p1 = new Person('Nick', 20);
p1.getName();

var p1 = new Person('Nick', 20);
首先我们知道,new的过程:新建对象,添加原型,改变this指向,返回对象。所以,这个Person函数的this指向新对象,随后新对象返回给了p1,我们可以说,这个this指向p1.
p1.getName();
执行getName(),这个方法被p1拥有,所以this指向p1

三 这样的问题

很多反直觉的事情发生:

var myObj = {
  name : "极客时间", 
  showThis: function(){
    console.log(this)
    function bar(){console.log(this)}
    bar()
  }
}
myObj.showThis()

你会以为bar的this和第一个this一样,其实不一样。函数bar中的this指向的是全局window对象,而函数showThis中的this指向的是myObj对象因为这个bar()是单独调用的,没有被某一个对象拥有。 所以你可以用一个self保存this。 也可以用箭头函数,箭头函数不会创建函数上下文,所以this就是继承调用函数的this。

四、总结

首先,在使用this时,为了避坑,你要谨记以下三点:

  1. 当函数作为对象的方法调用时,函数中的this就是该对象;
  2. 当函数被正常调用时,在严格模式下,this值是undefined,非严格模式下this指向的是全局对象window;
  3. 嵌套函数中的this不会继承外层函数的this值。 最后,我们还提了一下箭头函数,因为箭头函数没有自己的执行上下文,所以箭头函数的this就是它外层函数的this