摘要:在本教程中,您将学习在 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 undefined
Code language: JavaScript (javascript)
这意味着事件处理程序中的this.value
始终返回undefined
。
如前所述,箭头函数没有自己的this
值。它使用封闭词法作用域的this
值。在上面的示例中,箭头函数中的this
引用全局对象。
在 Web 浏览器中,全局对象是window
。window
对象没有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.count
为undefined
,因为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()); // 1
Code 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
对象的函数中使用箭头函数。