myfreax

什么时候不该使用箭头函数

箭头函数没有自己的 this 值和 arguments 对象。因此,你不应该将它用作事件的回调函数、字面量对象的方法、原型的方法

什么时候不该使用箭头函数
什么时候不该使用箭头函数

箭头函数没有自己的 this 值和 arguments 对象。因此,你不应该将它用作事件的回调函数、字面量对象的方法、原型的方法。

如果当你需要在函数使用 arguments 对象时,你也不应该使用箭头函数。在本教程中,您将了解在 ES6 什么时候不该使用箭头函数。

事件处理器

假设您的HTML代码有以下文本输入字段:

<input type="text" name="username" id="username" placeholder="Enter a username">

您希望在用户键入用户名时显示问候消息。下面将在  <div> 元素显示问候消息:

<div id="greeting"></div>

用户输入用户名后,您将捕获输入的当前值并将其更新到 <div> 元素:

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

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

Hello undefined

这意味着事件回调函数总是返回undefined

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

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

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

username.addEventListener('keyup', function () {
    input.textContent = 'Hello ' + this.value;
});

对象方法

请阅读以下 counter 对象:

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

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

下面计数器应该展示下一个值是 1:

console.log(counter.next());

但是,它返回 NaN

原因是当你在对象内部使用箭头函数时,它从封闭的词法作用域继承 this 值,在这个例子中是全局作用域。

this.countnext() 方法内部相当于 window.count (Web 浏览器)。

默认情况下 window.countundefined。因为 window 对象没有 count 属性。next() 方法在 undefined 的变量上再加 1 ,所以结果是 NaN

要解决此问题,您可以使用普通函数作为字面量对象的方法,如下所示:

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

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

console.log(counter.next()); // 1

原型方法

请阅读以下使用 prototype 模式的 Counter 对象:

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

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

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

this  值在 next()current() 方法中指向全局对象。由于您希望在这些方法中的  this 值指向 Counter 对象,因此您需要改用普通函数:

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

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

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

使用 arguments 参数对象的函数

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

例如,下面的 concat() 函数将不起作用:

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

相反,您可以这样使用普通函数​​:

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

结论

  • 箭头函数没有自己的 this 值。相反,它使用封闭词法作用域的 this 值。箭头函数也没有 arguments 对象。
  • 避免将箭头函数用于事件回调、字面量对象方法、原型方法和使用 arguments 对象的函数。

内容导航