ES6箭头函数没出现之前,this的指向不是函数被创建时绑定,而是被怎么样的方式调用时绑定的。而箭头函数刚好相反,箭头函数的this指向是函数被创建时绑定的,它的指向就是当前词法作用域中的this,并且不会因为被怎么样的方式调用改变绑定。
什么是词法作用域
首先我们必须了解JS的词法作用域,词法作用域是作用域的其中一个工作模型(另外一个是动态作用域,在js中只有this涉及动态作用域),词法作用域主要在代码的编译阶段,一个变量和函数的词法作用域取决于该变量和函数声明的地方。(而动态作用域是取决于变量和函数被调用的地方)。
4933701-178987bf6e37ee98.png

var str = 'window';
const obj = {
    str: 'obj',
    nativeFn: function() {
        console.log('当前的this指向', this.str);
        return function() {
            console.log('原生函数', this.str);
        }
    },
    arrowFn: function() {
        console.log('当前的this指向', this.str);
        return () => {
            console.log('箭头函数', this.str);
        }
    }
};
const obj2 = {
    str: 'obj2'
}
var nativeFn = obj.nativeFn(); //当前的this指向 obj
var arrowFn = obj.arrowFn(); //当前的this指向 obj
nativeFn(); //原生函数 window
arrowFn(); //箭头函数 obj

var str = 'window';
const obj = {
    str: 'obj',
    foo() {
        var str = 2
        console.log(this.str); //obj
        setTimeout(() => {
            console.log(this.str); //obj
        }, 100);
    }
}
obj.foo();

注意

var str = 'window';
const obj = {
    str: 'obj',
    fn: () => {
        console.log(this.str);
    }
}
obj.fn(); //window

这里有些人就迷惑了,竟然是'window',我们知道JS是没有快级作用域的,只有函数作用域和全局作用域,fn函数在创建的时候词法作用域为全局作用域,也就是window,所以箭头函数fn里面的this指向的也就是window.

var obj = {
    b: this, //window{}
    fn: function() {
        return () => {
            console.log(this.b);
        }
    }
}
console.log(obj.b); //window{}
var fn3 = obj.fn();
fn3(); //window{}

通过上面我们可以看到,this其实绑定的就是window对象,所以验证了obj对象里面的词法作用域是window,所以就很好理解了.

总结

普通函数中this(动态作用域)

  • 总是代表着它的直接调用者
  • 严格模式下(设置了'use strict'),this为undefined
  • 当使用call,apply,bind(ES5新增)绑定的,this指向绑定对象

ES6箭头函数中this(词法作用域)

  • this指向的是当前的词法环境
  • 即使是call,apply,bind等方法也不能改变箭头函数this的指向
Last modification:June 11th, 2020 at 10:21 pm
如果觉得我的文章对你有用,请随意赞赏