何时不使用箭头函数

摘要:在本教程中,您将学习在 ES6 中何时不应使用箭头函数。

一个箭头函数没有自己的this值和arguments对象。因此,您不应将其用作事件处理程序、对象字面量的属性方法、原型方法,或在您有一个使用arguments对象的函数时。

1) 事件处理程序

假设您有以下输入文本字段

<input type="text" name="username" id="username" placeholder="Enter a username">Code language: HTML, XML (xml)

您希望在用户输入用户名时显示问候消息。以下显示了将显示问候消息的<div>元素

<div id="greeting"></div>Code language: HTML, XML (xml)

一旦用户输入用户名,您就会捕获输入的当前值并将其更新到<div>元素中

const greeting = document.querySelector('#greeting');
const username = document.querySelector('#username');
username.addEventListener('keyup', () => {
  greeting.textContent = 'Hello ' + this.value;
});Code language: JavaScript (javascript)

但是,当您执行代码时,无论您输入什么,您都会收到以下消息

Hello undefinedCode language: JavaScript (javascript)

这意味着事件处理程序中的this.value始终返回undefined

如前所述,箭头函数没有自己的this值。它使用封闭词法作用域的this值。在上面的示例中,箭头函数中的this引用全局对象。

在 Web 浏览器中,全局对象是windowwindow对象没有value属性。因此,JavaScript 引擎将value属性添加到window对象并将它的值设置为undefined

要解决此问题,您需要使用常规函数。this值将绑定到触发事件的<input>元素。

username.addEventListener('keyup', function () {
    input.textContent = 'Hello ' + this.value;
});
Code language: JavaScript (javascript)

2) 对象方法

参见以下counter对象

const counter = {
  count: 0,
  next: () => ++this.count,
  current: () => this.count
};Code language: JavaScript (javascript)

counter对象有两个方法:current()next()current()方法返回当前计数器值,next()方法返回下一个计数器值。

以下显示了下一个计数器值,它应该为 1

console.log(counter.next());Code language: CSS (css)

但是,它返回NaN

原因是,当您在对象内部使用箭头函数时,它会继承来自封闭词法作用域的this值,在本例中是全局作用域。

next()方法内部的this.count等效于window.count(在 Web 浏览器中)。

默认情况下window.countundefined,因为window对象没有count属性。next()方法对undefined加 1,结果为NaN

要解决此问题,您可以将常规函数用作对象字面量的属性方法,如下所示

const counter = {
    count: 0,
    next() {
        return ++this.count;
    },
    current() {
        return this.count;
    }
};Code language: JavaScript (javascript)

现在,调用next()方法将按预期返回 1

console.log(counter.next()); // 1Code language: JavaScript (javascript)

3) 原型方法

参见以下使用原型模式的Counter对象

function Counter() {
    this.count = 0;
}

Counter.prototype.next = () => {
    return this.count;
};

Counter.prototype.current = () => {
    return ++this.next;
}Code language: JavaScript (javascript)

这些next()current()方法中的this值引用全局对象。由于您希望方法内部的this值引用Counter对象,因此您需要使用常规函数

function Counter() {
    this.count = 0;
}

Counter.prototype.next = function () {
    return this.count;
};

Counter.prototype.current = function () {
    return ++this.next;
}
Code language: JavaScript (javascript)

4) 使用 arguments 对象的函数

箭头函数没有arguments对象。因此,如果您有一个使用arguments对象的函数,则不能使用箭头函数。

例如,以下concat()函数将无法正常工作

const concat = (separator) => {
    let args = Array.prototype.slice.call(arguments, 1);
    return args.join(separator);
}Code language: JavaScript (javascript)

相反,您可以使用这样的常规函数

function concat(separator) {
    let args = Array.prototype.slice.call(arguments, 1);
    return args.join(separator);
}Code language: JavaScript (javascript)

总结

  • 箭头函数没有自己的this值。相反,它使用封闭词法作用域的this值。箭头函数也没有arguments对象。
  • 避免在事件处理程序、对象方法、原型方法和使用arguments对象的函数中使用箭头函数。
本教程对您有帮助吗?