sjn_hoho

sjn_hoho

JavaScript 中 this 是如何工作的?

废话

经历了一个非常紧急的迭代,加班加到怀疑人生,收拾心情,重新捡起 blog,争取做一个更博小能手。

之前印象

JS 中 this 的工作原理,是自古以来的必考点。有一句经典的话,谁最终调用函数,this 指向谁。这句话听起来好像很简单,但是结合各种场景,this 分别是如何指向的呢? ##具体场景

全局作用域

// global scope
foo = 'abc';
alert(foo); // abc

this.foo = 'def';
alert(foo); // def

在全局作用域/全局环境(global scope/global context)中,this 指向的就是全局变量 在浏览器中指的就是 window,在 node.js 中就是 global。

函数中

var boat = {
    size: 'normal',
    boatInfo: function() {
        alert(this === boat);
        alert(this.size);
    }
};

boat.boatInfo(); // true, 'normal'

var bigBoat = {
    size: 'big'
};

bigBoat.boatInfo = boat.boatInfo;
bigBoat.boatInfo(); // false, 'big'

从上述代码中可以看,同样是 boatInfo()打印出来确实不同的值,这是因为在任何函数中,this 的指向都不是静态的(static),它总是在你调用一个函数,但尚未执行函数内部代码前被指定,是由调用函数的父作用域提供的,这就是那句经典的话的来源。 接着上面在深一级

var boatInfo = bigBoat.boatInfo;
boatInfo();//false,undefined

这就是因为执行 boatInfo 函数的父作用域是全局,所以 this 指向了全局。

构造函数中

当使用 new 关键字去执行构造函数时,构造函数中的 this 指向的的就是新建的那个对象实例。

var thisArg;
function Ctor(){
    thisArg = this
}
var instance = new Ctor()
console.log(thisArg === instance) //true

箭头函数

当使用 es6 箭头函数时,默认绑定外层第一个不是箭头函数的 this,并且 this 一旦绑定,就不会被 call,apply,bind 改变。

var obj = {
     foo:()=>{
        console.log(this)
     }
}
obj.foo()//window|global

总结

this 的指向判断可以遵循一个方法,在非箭头函数下,通过()左边的对象,如果是一个引用,那么 this 就指向该对象,如果没有,就指向全局,如果有箭头函数存在,就绑定了外层第一个不是箭头函数的 this。