重读this: 箭头函数中的this

823 阅读2分钟

箭头函数是ES6的新特性,作为解决传统函数this指向难以追溯的方案(或者说不想写function关键字),按照部分技术文章的说法箭头函数中this的指向是固定的,但这样说容易让人认为箭头函数中的this永远指向同一个对象,到底是如何,我们来一探究竟。

this指向何方

今天重新翻阅了下你不知道的JS,发现它是这么描述箭头函数中的this指向的:

箭头函数中使用了当前的词法作用域覆盖了this本来的值,即继承了当前词法作用域作为this使用。

考虑如下代码:

const word = 'window hello'
const obj = {
    fn: function() {
        setTimeout(() => {
            console.log(this.word)
        })
    },
    word: 'hello'
}

obj.fn()

// hello
// 这是常见的箭头函数使用方式,绑定父级作用域,
// 避免了以往 const self = this的写法

那么此时此刻就可以无忧虑的调用fn,而不用担心fn内层回调的this指向吗?

显然是不行的,考虑如下代码

const word = 'window hello'
const obj = {
    fn: function() {
        setTimeout(() => {
            console.log(this.word)
        })
    },
    word: 'hello'
}

const globalFn = obj.fn;
globalFn();

const obj2 = {
    word: 'world',
    fn: obj.fn
}
obj2.fn();

// 上述代码的输出是什么呢?
// 答案是:globalFn输出"undefined", obj2.fn输出"world"

为什么输出会是这样的?

对于globalFn来说,此时调用方为window,globalFn的this指向window,而内部箭头函数继承了globalFn的this,所以也指向了window,而const的声明的变量不在window context上,所以最后输出undefined。

同理,obj2.fn,调用时fn的this指向obj2,内部箭头函数继承了fn的this对象,所以也指向了obj2,此时输出word。

结论

通过上述两个例子,我们可以发现箭头函数中的this并非一成不变,而是总是指向父级的this,而当父级是个function的时候,父级的this在不同调用环境下指向不同的对象(传统的this指向),而箭头函数总是继承这个this