JavaScript 中的箭头函数
箭头函数 在 ES6 中引入了 但是,您仍然需要了解何时使用传统函数与何时使用箭头函数,因为在某些情况下 使用箭头函数是错误的选择 。
句法
当你看到 =>
,您正在查看箭头函数。 声明箭头函数有两种方式:
- 没有花括号
{}
, 使用这种语法,箭头函数具有隐式返回。 例如,下面的箭头函数返回 42,即使没有return
。
// 'getAnswer()` is an arrow function that returns 42
const getAnswer = () => 42;
getAnswer(); // 42
- 带花括号
{}
,使用这种语法,箭头函数没有隐式return
。
// 'getAnswer()` is an arrow function that returns 42
const getAnswer = () => {
return 42;
};
getAnswer(); // 42
从箭头函数返回对象字面量很棘手:
// Syntax error! JavaScript assumes curly braces after `=>` means
// you're using the curly braces syntax
const getObj = () => { answer: 42 };
// With parentheses around the object literal, the below function
// correctly returns an object with `obj.answer = 42`
const getObj = () => ({ answer: 42 });
getObj(); // 42
没有花括号,你只能 表达式 在箭头右边 =>
,直观地说,这意味着您只能对单行使用无花括号语法。 您可以使用三元运算符 ?
, &&
, 和 ||
,但是你不能使用 if
语句或分号。
let answer = 42;
// Without curly braces, the arrow function can only contain one
// expression. The below function works fine, but you can't use
// an `if` statement without curly braces.
const getAnswer = () => answer !== null && answer !== undefined ?
answer :
0;
getAnswer(); // 42
参数
与普通函数一样,箭头函数可以采用零个或多个参数。
您必须将参数名称放在括号中 (param1, param2, param3) => {}
除非您的箭头函数只采用一个参数。
// If your arrow function takes no params, declare it with
// `() =>`
const getAnswer = () => 42;
// If your arrow function takes 1 param, you can omit the
// parentheses around the parameter names
let noop = v => v;
// Or, equivalently:
noop = (v) => v;
// If your arrow function takes more than 1 param, you must
// put parentheses around the parameter names
const add = (a, b) => a + b;
为什么是箭头函数?
箭头函数有两个主要优点:
- 单行函数的隐式返回意味着更简洁的 代码
this
,this
在箭头函数中是一样的this
在箭头函数之外。
例如,假设您尝试调用 setTimeout()
在一个 类方法 中。 如果您使用普通函数而不是箭头函数, this
不会指向 MyClass
。
class MyClass {
constructor(message) {
this.message = message;
}
print() {
setTimeout(function() {
// undefined, because `this` is a `Timeout` object in
// a `setTimeout()` callback
this.message;
}, 100);
}
}
const obj = new MyClass('Hello, World');
obj.message; // 'Hello, World'
obj.print();
带有箭头功能, this
将是一个实例 MyClass
。
class MyClass {
constructor(message) {
this.message = message;
}
print() {
setTimeout(() => {
// 'Hello, World'
this.message;
}, 100);
}
}
const obj = new MyClass('Hello, World');
obj.message; // 'Hello, World'
obj.print();
为什么不是箭头函数?
箭头函数非常出色,通常使用箭头函数还是普通函数都没有关系。 但是当你使用一个依赖于 this
,你不应该使用箭头函数。
例如,假设您 Vue 方法 使用箭头函数 您将无法访问 Vue 实例的 name
属性,因为 Vue 将无法设置 this
。
const Vue = require('vue');
const app = new Vue({
data: () => ({ name: '' }),
// This method will **not** work. Vue methods depend on
// the correct value of `this`
methods: {
setName: newName => this.name = newName
},
template: `
<div>
<h1>{{name}}</h1>
<button v-on:click="setName('Hello')"></button>
</div>
`
});
另一个常见的情况是 Mocha 超时 。 使用箭头函数 Mocha 测试 ,但是您不能设置测试超时。
describe('MyFunction', () => {
it('works', () => {
this.timeout(500); // Throws an error
});
});
一般来说,你不应该 将 箭头函数传递给框架,除非你不打算使用 this
关键词。 例如,不要对 Vue 方法、Mocha 测试、React 类方法或 Mongoose 模型方法 。 您可以在 Vue 方法或 Mocha 测试中使用箭头函数,但您提供给 Vue 或 Mocha 的顶级函数 不 应该是箭头函数。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论