【问题标题】:This not working as expected in nested arrow functions in ES6 [duplicate]这在 ES6 的嵌套箭头函数中无法正常工作 [重复]
【发布时间】:2017-08-20 17:46:20
【问题描述】:

我是箭头函数的新手,我不明白为什么我可以使用此代码:

const adder = {
    sum: 0,
    add(numbers) {
        numbers.forEach(n => {
            this.sum += n;
        });
    }
};

adder.add([1,2,3]);
// adder.sum === 6

...它工作得很好,但在以下情况下,this 没有正确绑定:

const adder = {
    sum: 0,
    add: (numbers) => {
        numbers.forEach(n => {
            this.sum += n;
        });
    }
};

adder.add([1,2,3]);
// Cannot read property sum

【问题讨论】:

  • 两种情况都写console.log(this)看看。
  • 我不明白为什么这被标记为重复。它不是关于一般的箭头函数,而是关于两个嵌套的箭头函数。

标签: javascript ecmascript-6 arrow-functions


【解决方案1】:

来自 MDN:

箭头函数表达式的语法比函数表达式短,并且不绑定自己的 this、arguments、super 或 new.target.(...)

这意味着在箭头函数内部,this 指的是最外面的this。如果在浏览器中运行,this 就是window 对象。

使用adder.sum 代替this.sum

Fiddle

【讨论】:

  • 对不起,我不明白。那么,在第一种情况下this.sum 指的是adder.sum 和第二种情况window.sum?为什么两者有区别?你说是最外层的this,其实这两个case应该是一样的。
  • 他们是。箭头函数不绑定到任何this。因此,当您访问 this.adder 时,您正在访问上下文中的第一个 this,可能是 window 对象。
【解决方案2】:

箭头函数允许到达词法this。这是定义adder 的上下文,而不是adder 本身。

预计会这样工作:

function Foo () {
    // this === foo;
    this.sum = 0;

    const adder = {
        sum: 0,
        add: (numbers) => {
            numbers.forEach(n => {
                // this === foo;
                this.sum += n;
            });
        }
    };

    adder.add([1,2,3]);
}

const foo = new Foo;

const adder = {
    sum: 0,
    add(numbers) { ... }
};

是一个快捷方式

const adder = {
    sum: 0,
    add: function (numbers) { ... }
};

所以add 方法在被称为adder.add(...) 时会将adder 作为this

【讨论】:

  • 当然,这里的adder.add 永远不会被调用,也不能被外部使用。
  • 谢谢,为了清楚起见,我已修复它。
  • 对不起,我不明白。为什么在第一种情况下this.sum 指的是adder.sum 或者这是一个错误的假设?
  • @DávidMolnár 在第一种情况下,add 是常规函数,它会根据调用方式获得动态this。当它像adder.add(...) 一样被调用时,它会得到adder 作为this,因为这是调用对象方法。这就是常规函数与箭头的不同之处(在重复问题中解释)。
  • 感谢对比示例,最有用!
猜你喜欢
  • 2018-07-10
  • 2017-06-22
  • 2016-03-25
  • 2018-08-01
  • 2018-06-15
  • 2017-02-05
  • 1970-01-01
  • 2018-08-02
相关资源
最近更新 更多