胖箭头函数(Fat arrow functions),又称箭头函数,是一个来自ECMAScript 2015(又称ES6)的全新特性。有传闻说,箭头函数的语法=>,是受到了CoffeeScript 的影响,并且它与CoffeeScript中的=>语法一样,共享this上下文。
箭头函数的产生,主要由两个目的:更简洁的语法和与父作用域共享关键字this。接下来,让我们来看几个详细的例子。
新的函数语法
传统的JavaScript函数语法并没有提供任何的灵活性,每一次你需要定义一个函数时,你都必须输入function () {}。
CoffeeScript如今之所以那么火,有一个不可忽略的原因就是它有更简洁的函数语法。更简洁的函数语法在有大量回调函数的场景下好处特别明显,让我们从一个Promise链的例子看起:
function getVerifiedToken(selector) { return getUsers(selector) .then(function (users) { return users[0]; }) .then(verifyUser) .then(function (user, verifiedToken) { return verifiedToken; }) .catch(function (err) { log(err.stack); }); }
以下是使用新的箭头函数语法进行重构后的代码:
function getVerifiedToken(selector) { return getUsers(selector) .then(users => users[0]) .then(verifyUser) .then((user, verifiedToken) => verifiedToken) .catch(err => log(err.stack)); }
以下是值得注意的几个要点:
function和{}都消失了,所有的回调函数都只出现在了一行里。
当只有一个参数时,()也消失了(rest参数是一个例外,如(...args) => ...)。
当{}消失后,return关键字也跟着消失了。单行的箭头函数会提供一个隐式的return(这样的函数在其他编程语言中常被成为lamda函数)。
这里再着重强调一下上述的最后一个要求。仅仅当箭头函数为单行的形式时,才会出现隐式的return。当箭头函数伴随着{}被声明,那么即使它是单行的,它也不会有隐式return:
const getVerifiedToken = selector => { return getUsers() .then(users => users[0]) .then(verifyUser) .then((user, verifiedToken) => verifiedToken) .catch(err => log(err.stack)); }
如果我们的函数内只有一条声明(statement),我们可以不写{},这样看上去会和CoffeeScript中的函数非常相似:
const getVerifiedToken = selector => getUsers() .then(users => users[0]) .then(verifyUser) .then((user, verifiedToken) => verifiedToken) .catch(err => log(err.stack));
你没有看错,以上的例子是完全合法的ES6语法。当我们谈论只包含一条声明(statement)的箭头函数时,这并不意味着这条声明不能够分成多行写。
这里有一个坑,当忽略了{}后,我们该怎么返回空对象({})呢?
const emptyObject = () => {}; emptyObject(); // "htmlcode">const emptyObject = () => ({}); emptyObject(); // {}下面是一个更完整的例子:
function () { return 1; } () => { return 1; } () => 1 function (a) { return a * 2; } (a) => { return a * 2; } (a) => a * 2 a => a * 2 function (a, b) { return a * b; } (a, b) => { return a * b; } (a, b) => a * b function () { return arguments[0]; } (...args) => args[0] () => {} // undefined () => ({}) // {}this
JavaScript中this的故事已经是非常古老了,每一个函数都有自己的上下文。以下例子的目的是使用jQuery来展示一个每秒都会更新的时钟:
$('.current-time').each(function () { setInterval(function () { $(this).text(Date.now()); }, 1000); });当尝试在setInterval的回调中使用this来引用DOM元素时,很不幸,我们得到的只是一个属于回调函数自身上下文的this。一个通常的解决办法是定义一个that或者self变量:
$('.current-time').each(function () { var self = this; setInterval(function () { $(self).text(Date.now()); }, 1000); });但当使用胖箭头函数时,这个问题就不复存在了。因为它不产生属于它自己上下文的this:
$('.current-time').each(function () { setInterval(() => $(this).text(Date.now()), 1000); });arguments变量
箭头函数与普通函数还有一个区别就是,它没有自己的arguments变量:
function log(msg) { const print = () => console.log(arguments[0]); print(`LOG: ${msg}`); } log('hello'); // hello再次重申,箭头函数没有属于自己的this和arguments。但是,你仍可以通过rest参数,来得到所有传入的参数数组:
function log(msg) { const print = (...args) => console.log(args[0]); print(`LOG: ${msg}`); } log('hello'); // LOG: hello关于yield
箭头函数不能作为generator函数使用。
最后
箭头函数是我最喜欢的ES6特性之一。使用=>来代替function是非常便捷的。但我也曾见过只使用=>来声明函数的代码,我并不认为这是好的做法,因为=>也提供了它区别于传统function,其所独有的特性。我个人推荐,仅在你需要使用它提供的新特性时,才使用它:
当只有一条声明(statement)语句时,隐式return。
需要使用到父作用域中的this。本文详细说明了JavaScript ES6新特性之一的箭头函数的使用方法和一些注意事项,大家在使用时一定要注意,箭头函数用好了是非常快捷的,如果用不好的话也是非常令人头痛的
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新动态
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]