ES6 中的箭头函数
ES6 引入了箭头函数。如果您在 ES6 发布之前学习过 JavaScript,或者您学习 JavaScript 时使用的资源尚未包含 ES6 的功能,那么箭头函数可能会让您感到有些困惑。这可能是因为它的语法与 ES5 JavaScript 的函数声明和表达式截然不同。然而,区别不仅仅在于语法,还包括this
关键字的作用域及其arguments
。本文旨在帮助我们理解所有这些。让我们从它的语法开始。
句法
我们将用一个例子来解释这一点。在 ES5 中,如果我们想使用 遍历数组,Array.prototype.map
我们会这样做。
var numbers = [3, 4, 5, 6];
var threeTimes = numbers.map(function(x) {
return x * 3;
});
console.log (threeTimes);//[9, 12, 15, 18]
如果我们要在 ES6 中重写该函数,我们将用右侧的粗箭头替换function
左侧的,如下所示:(x)
=>
var threeTimes = numbers.map((x) => {
return x * 3;
});
很简单吧?恭喜我们,我们刚刚创建了一个箭头函数。好消息是,它还可以进一步简化。由于该函数只接收一个参数,我们可以通过删除 周围的括号来进一步简化它x
。
var threeTimes = numbers.map( x => {
return x * 3
});
太棒了!不过要注意,如果参数不止一个,它们必须放在括号里。我们很快会看到一个例子。接下来,我们可以移除箭头后面的花括号,而不会造成任何影响,如下所示:
var threeTimes = numbers.map( x => return x * 3 );
所以我们现在只有一行函数。这个函数还可以进一步简化,但这会引出箭头函数语法的另一个特性——隐式返回。
隐性回报
这是什么意思?
也许理解与此相反的内容,即显式返回,可能会帮助我们更好地理解它。好吧,显式返回是指return
我们像上面的例子一样,通过书写来告诉函数返回什么。如果我们只返回一行代码,那么在箭头函数中这没有必要。隐式返回只是意味着,如果返回一行代码,则不必使用关键字return
. return
,如果箭头后有一个表达式,则是隐含的。这很酷,因为大多数返回语句通常只有一行代码。
所以我们的例子可以写成:
var threeTimes = numbers.map( x => x * 3);
看看箭头函数的语法有多简单?
关于箭头函数还有另外一点需要注意。
箭头函数是匿名的。
这意味着我们不能在 ES6 中这样做:
//ES5
function sayHello() {
...
}
上面的函数是一个命名函数。如果出现错误,并且你想知道错误调用的具体函数,那么命名函数就很有用。但是,如果我们希望函数有一个名称以便以后调用,则必须将其存储在变量中。下面给出了一个示例。
var square = x => x * x;
square(2); // 4
如果它是一个接收多个参数的函数,则将写为:
var add = (a,b) => a + b;
如果根本没有参数怎么办?我们可以简单地将函数写成:
var sayHello = () => "Hello";
var x = sayHello();// x = "Hello"
我猜你现在已经掌握了语法。我们应该进一步讨论箭头函数的另一个特性——词法作用域this
。
this
箭头函数的词法作用域
this
即使是使用 JavaScript 多年的开发者,也可能会对“.”这个词感到困惑。为了解释这一点,我将举一个例子。我们想创建一个计数器,用来增加秒数。
//ES5
function counter() {
this.seconds = 0;
this.setInterval(function() {
this.seconds++;
console.log(this.seconds);
}, 1000);
}
counter();
我们可能希望它能正常工作,并且this.seconds
每秒都会增加。但实际上你得到的是这样的。
//NaN
//NaN
//NaN
//NaN
为什么会发生这种情况?这是因为在 ES5 中,每个函数都会绑定自己的this
。因此,在setInterval
函数中,this.seconds
并不引用其父级this.seconds
,而是引用窗口的 ,而窗口的this.seconds
并非数字。
为了在 ES5 中解决这个问题,我们要么将父级 存储this
在变量中,然后像下面这样使用它
//ES5
function counter() {
this.seconds = 0;
var that = this;
this.setInterval(function() {
that.seconds++;
console.log(that.seconds);
}, 1000);
}
setInterval
或者我们像这样将 this 绑定到函数。
//ES5
function counter() {
this.seconds = 0;
this.setInterval(function() {
this.seconds++;
console.log(this.seconds);
}bind(this), 1000);
}
在 ES6 中,你无需承受所有这些压力,因为箭头函数不会绑定自身的this
。相反,this
箭头函数始终引用其父级的this
。箭头函数继承其父级的作用域。因此,上述示例可以重写为
//ES6
function counter() {
this.seconds = 0;
this.setInterval(() => {
this.seconds++;
console.log(this.seconds);
}, 1000);
}
所以this
值实际上并没有绑定到箭头函数。this
箭头函数中的 实际上是从其父级词法获取的。它没有this
,所以当你使用 时this
,你引用的是外部作用域。
无参数约束
就像的情况一样this
,箭头函数不会绑定它们自己的arguments
对象。arguments
箭头函数中的 只是对封闭范围的参数的引用。因此我们可以这样做:
var arguments = [1, 2, 3];
var arr = () => arguments[0];
arr();//1
它之所以有效是因为它引用了其父级的参数。
以上就是关于箭头函数你应该了解的内容。如果你想进一步参考,MDN是个不错的选择。
有任何问题或补充?请留言。
感谢您的阅读:)
文章来源:https://dev.to/sarah_chima/arrow-functions-in-es6-24