ES2015 - ES2020及以后的新玩具
这一章讲了什么?
- 定义,谁是谁,还有术语
- JavaScript版本说明(ES6?ES2020 ?)
- 什么是“新玩具”?
- 驱动新JavaScript特性的过程
- 使用下一代JavaScript的工具
下载本章的代码
您可以在以下网站下载本章的代码https://thenewtoys.dev/bookcode
或https://www.wiley.com/go/javascript-newtoys
.
JavaScript在过去几年中发生了很大的变化。
如果你在21世纪初是一名活跃的JavaScript开发人员,那么在一段时间内,你可能会认为JavaScript停滞不前。在1999年12月的第3版规范之后,开发人员足足等了10年才出现下一版规范。从外面看,好像什么都没发生。事实上,很多工作正在进行;它只是没有进入官方规范和多个JavaScript引擎。我们可以(但不会)用一整章——如果不是一本书的话——来讲述在-à-vis JavaScript的重要位置上的不同团队在做什么,以及他们如何在一段时间内无法就共同的前进道路达成一致。关键是,在2008年7月奥斯陆的一次决定性会议上,经过多次事先谈判,他们最终就前进的道路达成了一致。Brendan Eich (JavaScript的创造者)后来称之为Harmony的共同基础,为2009年12月的第5版规范铺平了道路(第4版从未完成),并为持续的进展奠定了基础。
我的,事情是如何发展的。
在本章中,您将了解2009年以来的新特性(本书其余部分将详细介绍)。您将了解谁负责推动JavaScript向前发展,现在使用了什么进程来实现这一点,以及如何跟踪即将发生的事情并在愿意的情况下参与其中。您将了解可以用来编写现代JavaScript的工具,即使您的目标环境还没有跟上。
定义,谁是谁,还有术语
为了讨论JavaScript的情况,我们需要定义一些名称和常用术语。
Ecma吗?ECMAScript吗?TC39吗?
我们所认为的“JavaScript”是由Ecma International标准化的“ECMAScript”,1负责多种计算标准的标准组织。ECMAScript标准为ECMA-262。该标准的负责人是Ecma国际技术委员会39(“TC39”)的成员,负责“通用、跨平台、与供应商无关的编程语言ECMAScript的标准化”。这包括语言语法、语义、库和支持该语言的补充技术。”2他们也管理其他标准,如JSON语法规范(ECMA-404),以及著名的ECMAScript国际化API规范(ECMA-402)。
在这本书中,在常见的用法中,JavaScript是ECMAScript,反之亦然。有时候,特别是在不同的团队做不同的事情的十年里,“JavaScript”被用来专门指Mozilla开发的语言(它有一些功能要么从未被纳入ECMAScript,要么在ECMAScript之前发生了显著的变化),但自从Harmony以来,这种用法越来越过时了。
ES6吗?ES7吗?ES2015吗?ES2020吗?
所有这些不同的缩写可能会令人困惑,尤其是因为一些有版本号,而另一些有年份。本节将解释它们是什么以及为什么有两种类型。
直到第5版,TC39通过版本号来引用规范的版本。第5版规范的完整标题是:
- 标准ecma - 262
- 第五版/ 2009年12月
- ECMAScript语言规范
因为“ECMAScript第5版”有点拗口,所以说“ES5”是很自然的事情。
从2015年的第6版开始,TC39采用了持续改进的流程,其中规范是一个活编辑的草案3.有年度快照。(本章稍后会详细介绍。)当他们这样做时,他们在语言名称中添加了年份:
- 标准ecma - 262
- 第六版/ 2015年6月
- ECMAScript®2015语言规范
所以ECMAScript第6版标准(“ES6”)定义了ECMAScript 2015,简称“ES2015”。在出版之前,“ES6”已经成为了一个流行词,并且仍然被广泛使用。(不幸的是,它经常被不准确地使用,不仅指来自ES2015的特性,还指后来在ES2016、ES2017等中出现的特性。)
这就是为什么有两种样式,使用版本的样式(ES6, ES7,…)和使用年份的样式(ES2015, ES2016,…)。你用什么取决于你自己。ES6是ES2015(有时不正确地是ES2015+), ES7是ES2016, ES8是ES2017,以此类推,直到(截至本书发布)ES11,即ES2020。您还将看到“ESnext”或“ES”。Next”,有时用来指即将到来的变化。
在这本书中,我使用了我所看到的新兴共识:旧的风格用于ES5和更早的版本,新的风格用于ES2015和更晚的版本。
综上所述,尽管我通常会指出某个特性被引入的具体版本,但事实上Array.prototype.includes
来自ES2016和Object.values
来自ES2017并不重要。更重要的是,您的目标环境实际支持什么,以及您是否需要避免使用特定的特性,还是需要对其进行编译和/或填充。(在后面的“在昨天的环境中使用今天的玩具,今天的明天的玩具”一节中有更多关于翻腾和填充的内容。)
JavaScript“引擎”,浏览器和其他
在本书中,我将使用术语“JavaScript引擎”来指代运行JavaScript代码的软件组件。JavaScript引擎必须知道如何:
- 解析JavaScript,
- 要么对其进行解释,要么将其编译为机器代码(或两者兼有),然后
- 在按照规范描述的工作环境中运行结果。
JavaScript引擎有时也被称为虚拟机,或简称vm。
JavaScript引擎的一个常见位置当然是在web浏览器中:
- 谷歌的Chrome浏览器使用他们的V8引擎(也用于Chromium、Opera和Microsoft Edge v79及更高版本),除了iOS(稍后会详细介绍)。
- 苹果的Safari浏览器(适用于Mac OS和iOS)使用他们的JavaScriptCore引擎。
- Mozilla的Firefox使用他们的SpiderMonkey引擎,除了在iOS上。
- 微软的ie浏览器使用他们的JScript引擎,这个引擎越来越过时,因为它只得到安全补丁。
- Microsoft Edge v44及更早版本(“Legacy Edge”)使用Microsoft的Chakra引擎。2020年1月,Edge v79发布了,它基于Chromium项目,使用V8引擎(iOS除外)。(版本号从44跃升至79,以与Chromium保持一致。)Chakra仍然在使用Microsoft WebView控件的各种产品中使用,例如Microsoft Office JavaScript插件,尽管它可能在某个阶段被替换。(WebView2使用Chromium Edge,截至2020年初已进入开发者预览版。)
Chrome、Firefox、Edge和其他在苹果iPad和iPhone iOS操作系统上运行的浏览器目前不能使用自己的JavaScript引擎,因为要编译和运行JavaScript(而不仅仅是解释它),它们必须分配可执行内存,而且只有苹果自己的iOS应用程序可以这样做,其他供应商的应用程序不能这样做。所以Chrome和Firefox(以及其他浏览器)不得不在iOS上使用苹果的JavaScriptCore,尽管它们在桌面和Android上使用自己的引擎。(至少现在是这样;V8团队在2019年为V8添加了“仅解释器”模式,这意味着Chrome和其他使用V8的用户可以在iOS上使用该模式,因为它不需要使用可执行内存。)在这本书中,如果我说某些东西“由Chrome支持”或“由Firefox支持”,我指的是分别使用V8或SpiderMonkey的非ios版本。
JavaScript引擎也用于桌面应用程序(Electron,4本机反应,5和其他),web服务器和其他类型的服务器(通常使用Node.js6)、非web应用程序、嵌入式应用程序——几乎无处不在。
什么是“新玩具”?
在这本书中,“新玩具”是指在ES2015到ES2020期间添加到JavaScript中的新功能(以及预览一些即将推出的功能)。在这六次更新中,该语言已经取得了长足的进步。以下是一个大致的概述。(附录A有一个更完整的变更列表。)清单上的一些术语可能不太熟悉;别担心,你会在整本书中学习到它们。
- 选择加入区块范围(
让
,常量
):更窄的变量范围,巧妙的处理为
循环体作用域,值不能改变的“变量”(常量
) - “箭头”函数:轻量级、简洁的函数,对于回调特别有用,因为它们关闭
这
而不是拥有自己的这
在调用时设置的值 - 函数参数的改进:默认值;参数解构,“rest”参数,后面的逗号
- 可迭代对象:用于创建和使用可迭代对象(如数组和字符串)的定义良好的语义,语言内迭代构造(
的
,for-await-of
);生成器函数,用于生成可迭代的序列(包括异步序列) - “扩展”语法:将数组(或其他可迭代对象)项展开到新的数组中,将对象属性展开到新的对象中,将可迭代项展开到离散的函数参数中;特别适用于函数式编程,或任何使用不可变结构的地方
- “Rest”语法:将对象属性、可迭代对象的值或函数的参数的“Rest”集合到一个对象或数组中
- 其他语法改进:在调用函数时,允许参数列表中以逗号结尾;中省略未使用的标识符
抓
条款;新型八进制字面值;二进制文本;数字字面值中的分隔符;和更多的 - 析构:以一种反映对象和数组文字语法的简洁方式从数组/对象中挑出值
类
:显著简化的声明性语法,用于创建构造函数和相关的原型对象,同时保留JavaScript固有的原型性质- 异步编程改进:承诺,
异步
功能和等待
;这明显减少了“回调地狱” - 对象文字改进:计算属性名、简写属性、方法语法、属性定义后的尾随逗号
- 模板字面量:一种简单的、声明性的方法,用于创建具有动态内容的字符串,并使用带标签的模板函数来超越字符串
- 类型化数组:用于使用本机api(以及更多)的低级真数组
- 共享内存:在JavaScript线程之间真正共享内存的能力(包括线程间协调原语)
- Unicode字符串改进:Unicode码点转义序列;支持访问代码点而不是代码单元
- 正则表达式改进:后视断言;命名捕获组;捕捉指数;Unicode属性转义;Unicode大小写不敏感
- 映射:键/值集合,其中键不必是字符串
- 集合:语义定义良好的唯一值的集合
- WeakMap、WeakSet和WeakRef:只保存对对象的弱引用的内置组件(允许它们被垃圾收集)
- 标准库添加:新方法
对象
,数组
,Array.prototype
,字符串
,String.prototype
,数学
,及其他 - 支持动态元编程:
代理
而且反映
- 符号:保证唯一的值(对于唯一的属性名特别有用)
- BigInt:任意精确整数
- 很多很多其他的
所有这些新特性,尤其是新语法,可能会让人难以承受。别担心!没有必要采用新的特性,除非你已经准备好并且需要它们。TC39坚持的关键原则之一是“不要破坏网络”。这意味着JavaScript必须保持“网络兼容”——也就是说,与当今世界上已经存在的大量代码兼容。7如果你不需要一个新功能,或者你不喜欢一个新功能,你就不必使用它。无论该功能做什么,您的旧方法都将继续工作。但在许多情况下,您可能会发现有一个令人信服的理由使用新特性,特别是新的语法特性:它们使编写和理解更简单,更不易出错,或者在代理
而且WeakMap
/WeakSet
共享内存等等——它们实现了没有它们大部分无法完成的事情。
由于篇幅原因,本书只介绍了JavaScript规范本身ECMA-262中的新玩具。但是在ECMAScript国际化API规范中有一些令人兴奋的新玩具8还有ECMA-402,非常值得一读。您可以在本书的网站上找到ECMA-402的覆盖范围https://thenewtoys.dev/internationalization
.
新玩具是如何被创造出来的?
在本节中,您将了解谁负责推动JavaScript向前发展,他们使用什么过程来完成这项工作,以及如何遵循和参与这个过程。
谁负责
您在前面了解到Ecma国际技术委员会39 (TC39)负责创建和发布ECMAScript标准的更新规范。该委员会由JavaScript开发人员、框架作者、大型网站作者/维护者、编程语言研究人员、所有主要JavaScript引擎的代表、有影响力的JavaScript开发者以及JavaScript成功和未来的其他利益相关者组成。他们定期举行会议,历史上每年六次,为期三天。要以成员身份参加会议,您的组织可以加入Ecma。9TC39克服了开发人员的需求、实现的复杂性、安全问题、向后兼容性和许多其他设计输入的困难,为JavaScript社区带来了新的有用的特性。
为了确保委员会作为社区的一部分而不是独立于社区,TC39维护了ecma262 GitHub存储库10使用最新的规范(可在https://tc39.es/ecma262/
)及建议资料库11参阅通过下一节所述TC39流程的提案。一些成员还活跃在TC39话语组。12TC39会议的会议记录和相关材料(幻灯片等)已张贴至https://github.com/tc39/notes
.
你可以在这里了解更多关于TC39的信息,以及如何参与其中https://tc39.es/
.您还可以了解更多关于TC39如何工作的信息https://github.com/tc39/how-we-work
.
这个过程
TC39在2013年11月采用了一个定义良好的过程,并于2014年1月首次发布。TC39将提案通过多个阶段(阶段0到阶段4),每个阶段都有明确的期望,从一个阶段过渡到下一个阶段有明确的标准。一旦提案符合进入下一阶段的标准,委员会就会以协商一致的方式决定是否将其推进。
流程文件本身值得一读,13但简而言之,这些阶段是:
- 阶段0——稻草人:有些人有了一个他们认为值得考虑的想法,所以他们考虑了一下,把它写下来,然后提出了。(这个阶段几乎不是一个阶段,这个术语在不同的时间被用于不同的事情。)如果提出提案的人不是TC39成员,他们需要注册为非成员贡献者14(任何人都能做到)。一些阶段0的提案最终会被列出在TC39提案库中,但其他的没有;通常情况下,只有那些获得了潜在冠军的人是委员会成员。如果第0阶段的提案获得足够的关注,TC39成员可将其列入TC39会议议程,以便在第1阶段进行讨论和审议。
- 第一阶段-提案:一旦提案被提交给委员会,并且达成了进一步调查的共识,委员会就会进入第一阶段,并有一位冠军来指导它完成整个过程。如果还没有一个GitHub回购,发起人或拥护者或其他感兴趣的方会创建一个。然后社区成员(无论是否在委员会中)讨论它,进一步开发它,研究其他语言或环境中的类似技术,细化范围,找出解决方案的一般形式,并通常充实想法。作为这项工作的结果,结果可能是收益不值得付出代价,或者这个想法可能需要被打破,并添加到其他建议中,等等。但是,如果提案有依据,相关人员(他们可能会随着时间的推移而改变)将把一些初始的规范语言、API和语义草案放在一起,并将其提交给TC39,以便在第二阶段进行考虑。
- 第二阶段-草案:当准备就绪时,第一阶段的提案可以在TC39会议上提出,以供第二阶段考虑。这意味着寻求共识,认为提案应该继续进行,并期望它可能会经历整个过程。阶段2是社区细化精确语法、语义、API等并使用正式规范语言详细描述解决方案的阶段。通常,腻子和/或巴别塔插件都是在这个阶段创建的,以便进行实际使用的试验。根据其范围的不同,一项提案可能会停留在第二阶段一段时间,以制定细节。
- 第三阶段-候选人:一旦团队将提案成熟为最终草案,并为其创建了正式的规范语言,冠军就可以将其提交到第三阶段。这意味着寻求共识,即提案已经准备好在JavaScript引擎中实现。在阶段3,提案本身几乎是稳定的。在这一点上的变化预计将仅限于实现驱动的反馈,例如在实现过程中发现的极端情况,web兼容性问题,或实现的困难。
- 阶段4 -完成:此时,特性已经完成,可以添加到编辑器的草稿中
https://tc39.es/ecma262/
.为了达到这一最后阶段,该功能必须在TC39的test262测试套件中进行验收测试;15至少有两个不同的兼容实现通过了测试(例如,在V8版本的Chrome Canary和SpiderMonkey版本的Firefox Nightly,或SpiderMonkey版本的Firefox和JavaScriptCore版本的Safari Tech Preview等)。一旦满足了这些条件,进入阶段4的最后一步是,开发该特性的团队向ecma262存储库发送拉取请求,将规范更改合并到编辑器的草案中,ECMAScript编辑组接受该PR。
这是提案成为JavaScript一部分的过程。但并不是所有的改变都是建议。可以在TC39会议上根据对规范的pull请求达成一致意见,从而进行较小的更改。的输出Date.prototype.toString
在ES2017和ES2018之间发生了变化(见第17章),这是对pull request达成共识的结果,而不是一个分阶段的提案。通常,这些是编辑性的改变,或者是反映JavaScript引擎已经做了什么,但在规范中没有的改变,或者是对规范说要做的改变已经达成一致,因为TC39认为它们是理想的和“web兼容”(不会破坏大量现有代码),比如ES2019中的改变Array.prototype.sort
稳定排序(参见第11章)。如果您想知道正在考虑或以这种方式进行哪些更改,请查看列表中的“需求共识”标签https://github.com/tc39/ecma262
回购(和类似的https://github.com/tc39/ecma402
ECMA-402变更的回购)。要找到已完成的,请查看“已达成共识”、“编辑更改”和/或“规范更改”标签。在某种程度上,对于这些“需求共识”的变化可能会有一个更正式的过程,但现在,这是您观察它们的方式。
参与
如果你看到一个你感兴趣的提议,你想参与,你应该什么时候去做?这种参与应该是什么样的?
关键的一点是:尽早参与。一旦提案进入阶段3,通常只考虑基于实现经验的关键更改。参与的最佳时间是阶段0、1和2。这时你可以根据自己的经验提供见解,帮助定义语义,使用像Babel这样的工具(你将在后面的部分中了解到)尝试被提议的内容等等。这并不是说您在阶段3的提案中找不到有用的角色(有时需要完成巩固规范文本或帮助编写开发人员文档方面的任务),只是要注意,在阶段3建议更改通常是没有用的,除非您是在JavaScript引擎中实现它的人之一,并且遇到了问题。
所以:你已经找到了一个你想参与的提案;现在该做什么?这取决于你,但这里有一些建议:
- 做好调查。阅读提案的解释
README.md
与TC39提案列表相关联)和其他文件紧密而仔细地联系在一起。如果它们涉及到现有技术(例如另一种语言中的类似功能),那么阅读现有技术是很有用的。如果有初始规范文本,请阅读它。(以下指南可能会有帮助:https://timothygu.me/es-howto/
)。您希望确保您提供的输入是消息灵通的。 - 试试这个功能吧!即使您还不能使用它,您也可以编写推测代码(不能运行但可以考虑的代码),以考虑该建议在多大程度上解决了它打算解决的问题。如果有一个Babel插件,试着编写和运行代码。看看这个功能是如何为你工作的,并提供反馈。
- 寻找你能提供帮助的方法。除了建议和反馈,还有很多方法可以帮助你完成提案。例如,你可以寻找已经达成共识的问题,但没有人有时间去做(研究现有技术,更新解释器,更新规范文本)。你可以做这些更新,如果你觉得舒服的话。您可以通过讨论GitHub问题中的贡献来与提案作者进行协调。
当你参与其中时,记得要尊重每个人,友好、耐心、包容和体贴。注意你的用词。你更可能通过善待他人和展现合作精神来产生影响力,而不是通过表现出愤怒、轻蔑或阻碍。请注意,TC39的会议和用于制定提案的在线空间受《行为准则》的约束。16如有不当行为,请向TC39行为准则委员会咨询(见链接文件)。
跟上新玩具的步伐
你不需要跟上新玩具的步伐。正如我所提到的,你过去做事的方式不会消失。但如果你正在读这本书,我猜你会想知道。
在您之前阅读该过程时,有一件事可能会让您感到困扰,即该过程确保新特性在添加到规范之前进入现实世界。相比之下,当ES5和ES2015分别于2009年和2015年发布时,他们所描述的大多数特性(以描述的形式)在当时的任何JavaScript引擎中都不存在。如果规范遵循了新特性,而不是相反,你如何跟上接下来的特性呢?这里有一些方法:
- 观看GitHub上的建议存储库(
https://github.com/tc39/proposals
).如果某样东西进入了第三阶段,它可能会在一两年内被添加进去。即使是阶段2的特性最终也至少有可能被添加,尽管TC39几乎在任何阶段都可能拒绝任何特性。 - 浏览TC39会议的会议记录
https://github.com/tc39/notes
. - 参与TC39话语组(
https://es.discourse.group/
).17 - 请注意下一节中讨论的工具的情况。
您也可以在https://thenewtoys.dev
,在那里我将继续报道接下来将发生的事情。
在昨天的环境中使用今天的玩具,在今天使用明天的玩具
就仅仅学习本书所涵盖的特性而言,您不需要担心如何处理不支持这些特性的环境;几乎所有涉及的内容(除了第18章和第19章)都被当前版本的Chrome、Firefox、Safari和Edge桌面浏览器和Node.js至少支持。只需使用其中之一来运行代码。
使用node.js运行示例
默认情况下,当你用Node.js运行一个脚本时,像这样:
节点脚本.js
它在模块范围内运行,而不是全局范围。本书中的一些示例演示了仅在全局范围内发生的事情,因此当您以这种方式运行代码时,它们将不起作用。
对于这些例子,要么使用浏览器运行代码,要么使用Node.js的读/求值/打印循环(REPL)。方法的参数指定要运行的脚本文件,以使用REPL节点
命令。方法将脚本重定向到其中<
operator(这在Unix/Linux/Mac OS系统和Windows上都适用):
节点<脚本.js
当一个示例需要在全局范围内运行时,我会提醒您这样做。
但是,在某些阶段,您可能希望在不支持这些新特性的环境中使用它们。例如,大多数JavaScript开发仍然以web浏览器为目标,不同浏览器中的JavaScript引擎在不同的时间获得新特性(如果internet Explorer不支持本书中讨论的任何新特性的话)。18但在撰写本文时仍有一些全球市场份额,特别是在政府和大公司的内部网中)。
这是ES5发布时的一个问题,因为当时在任何发布的JavaScript引擎中都很少实现它。但是ES5的大部分是新的标准库特性,而不是重大的语法变化,所以可以使用各种项目来“填充”(通过包括一个额外的脚本来提供缺少的对象/函数),比如ES5 -shim.js,19core-js,20.es-shims,21或类似的。在2010年到2015年ES2015的开发过程中,很明显,要想很好地开发新语法,需要有新语法的实际经验,但JavaScript实现还没有新语法——这显然是一个两难的局面。
工具构建者来拯救!他们创造了像Traceur这样的工具22和巴别塔23(以前的6to5),它将使用新语法的源代码作为输入,将其转换为使用旧语法的代码,并输出旧风格的代码(可选地,连同填充程序和其他运行时支持函数)。同样,打印稿24在规范完成之前就支持了ES2015的主要部分。这些工具允许您编写新风格的代码,但在将其交付到旧环境之前,可以将其转换为旧风格的代码。这种转换过程被称为“编译”或“编译”。最初,这对于针对ES2015计划中的JavaScript改进的反馈很方便,但即使ES2015出来了,如果你打算在一个没有新特性的环境中运行它,这也是一种编写新风格代码的有用方法。
在撰写本文时,Traceur已经销声匿迹,但Babel仍被世界各地的JavaScript开发人员所使用。Babel对过程中几乎所有的特性都进行了转换,甚至是阶段1中的特性,这些特性在进展之前可能会发生显著的变化。(所以使用这些工具的风险自负。第三阶段以后使用起来相当安全。)您选择想要使用的转换插件,使用这些特性编写代码,Babel生成的代码可以在没有这些特性的环境中使用。
用巴别塔翻译一个例子
在本节中,我们将快速了解如何使用Babel将ES2015特性(称为箭头函数)的代码转换为在IE11上运行的es5兼容代码。但这只是一个例子;你也可以很容易地使用Babel将尚未出现在任何JavaScript引擎中的Stage 3特性转换为兼容es2020的代码。Babel还支持一些根本不在进程中的转换,比如JSX25(在一些JavaScript框架中使用,特别是React26).真正有冒险精神的人可以编写自己的转换插件,只用于他们的项目!
要安装Babel,你需要Node.js和npm
(节点包管理器)。如果你的系统上还没有安装:
- 去
https://nodejs.org/
并使用适合您的系统的安装程序/包来安装它;或 - 使用节点版本管理器,它提供了一种方便的方法来安装节点版本并在它们之间切换:
https://github.com/nvm-sh/nvm
npm
与Node.js捆绑在一起,所以你不必单独安装它。
一旦你安装了它们:
- 为这个例子创建一个目录(例如,
例子
在您的主目录中)。 - 打开命令提示符/终端窗口,切换到刚才创建的目录。
- 使用
npm
要创建package.json
文件:类型npm init
,按“Enter”。
npm
会问一系列的问题;按你喜欢的方式回答问题(或者按Enter键回答所有问题)。完成后,它将输出package.json
到示例目录。 - 接下来,安装Babel。(以下步骤从去到
https://babeljs.io/docs/setup/#installation
然后点击命令行按钮;你可能想查看那里的最新消息。)类型NPM install——save-dev @babel/core @babel/cli
,按“Enter”。
npm
将下载并安装Babel、它的命令行界面以及它的所有依赖项到您的示例项目中。(您可能会得到一个与名为fsevents
和/或一些弃用警告;没关系。) - 此时,您可以通过直接调用Babel来开始使用它,但是让我们通过添加一个
npm
的脚本输入package.json
.开放package.json
在你最喜欢的编辑器中。如果没有顶层脚本
条目,创建一个npm
会包括一个带测验
显示错误的脚本)。在脚本
条目,添加此设置:“构建”:"babel SRC -d lib"
现在你的
package.json
应该类似于清单1-1。(你的可能还有一个测验
进入脚本
;这很好。它也可能有不同的许可证,我总是将默认更改为MIT。)确保保存文件。
清单1-1:示例package.json-package.json
{“名称”:“例子”,“版本”:“1.0.0”,“描述”:"",“主要”:“index.js”,“脚本”:{“构建”:"babel SRC -d lib"},“作者”:"",“许可证”:“麻省理工学院”,“devDependencies”:{“@babel / cli”:“^”7.2.3,“@babel /核心”:“^ 7.2.2”}}
- 巴别塔高度模块化。虽然我们已经安装了它,但我们还没有告诉它做任何事情。对于这个例子,我们将使用它的一个预置,通过安装和配置预置,告诉它将ES2015代码转换为ES5代码。要安装预设,请键入
NPM install——save-dev babel-preset-env
,按“Enter”。在下一步中,我们将配置它。
- 现在我们需要为Babel创建一个配置文件,
.babelrc
(注意前面的圆点)。用这些内容创建文件(或使用章节下载中的文件):{“预设”:[[“env”,{“目标”:{“即”:“十一”}}]]}
该配置告诉Babel使用它的env
预设,Babel文档描述为“…一个智能预设,允许你使用最新的JavaScript,而不需要微管理哪些语法转换…是你的目标环境所需要的。”在本配置中,设置目标器“即”:“十一”
讲述了env
预设你的目标是IE11,这适用于下面的例子。方法的文档对于您的实际使用是有帮助的env
预设27和/或其他你可能想要使用的预设或插件。
这就是本例中的Babel设置。现在让我们创建一些代码来编译它。的子目录例子
目录称为src
,并在其中创建一个名为index.js
使用清单1-2的内容。(在这个过程的最后,我将向您展示一个文件应该放在哪里的列表,所以如果您有点不确定,也不用太担心;只需创建文件,如果文件放在错误的位置,可以移动它。)
清单1-2:ES2015编译示例input-index.js
varobj={雷克斯:/\ d/,checkArray:函数(数组){返回数组.一些(条目= >这.雷克斯.测验(条目));}};控制台.日志(obj.checkArray([“不”,“数字”,“在”,“这”,“数组”]));/ /错误控制台.日志(obj.checkArray([“这”,“数组”,“已经”,“1”,“数字”]));/ /正确的
清单1-2中的代码只使用了一个ES2015+特性:箭头函数this.rex.test(Entry)
在调用一些
,我在代码中突出显示了它。(是的,这确实是一个函数。)你将在第三章学习箭头函数。简单的、不完整的版本是,它们提供了一种简洁的方法来定义函数(如您所见),并且它们关闭了这
就像关闭一个变量(而不是有这
由它们的名称设置)。当obj.checkArray(…)
被调用时,这
内调用的引用obj
即使在一些
回调,所以this.rex
指雷克斯
属性obj
.如果回调是一个传统函数,这就不成立了。
此时,你的示例目录应该包含以下内容:
例子/+−−node_modules/|+−−(各种目录和文件)+−−src/|+−−指数.js+−−.babelrc+−−包.json+−−包-锁.json
你已经准备好了!类型
NPM运行构建
,按“Enter”。巴别塔会做自己的事,创造自由
输出目录为您,并编写ES5版本的index.js
到它。结果是lib / index.js
将类似于清单1-3。
清单1-3:ES2015编译示例output-index-transpiled-to-es5.js
“使用严格的”;varobj={雷克斯:/\ d/,checkArray:函数checkArray(数组){var_this=这;返回数组.一些(函数(条目){返回_this.雷克斯.测验(条目);});}};控制台.日志(obj.checkArray([“不”,“数字”,“在”,“这”,“数组”]));/ /错误控制台.日志(obj.checkArray([“这”,“数组”,“已经”,“1”,“数字”]));/ /正确的
如果你比较一下src / index.js
(清单1-2)到lib / index.js
如清单1-3所示,您将只看到几个变化(除了空白)。首先,巴别尔增加了一个“使用严格的”;
(回想一下,严格模式是ES5中添加的一个特性,它修改了一些由于各种原因而出现问题的东西的行为)。这是Babel的默认设置,但如果您的代码依赖于松散模式,则可以将其关闭。
有趣的是,它重写了箭头函数。它在内部创建了一个变量checkArray
被称为_this
,设置为这
,然后用传统的函数作为一些
回调;在函数中,它使用_this
而不是这
.这符合我之前对箭头函数的描述——它们关闭这
就像封闭变量一样。Babel只是以ES5环境可以理解的方式实现了这一点。
这显然只是一个非常小的示例,但它说明了这一点,并让您了解了在项目中需要这样做时可能使用的工具。Babel可以集成到您的构建系统中,无论您使用Gulp,28繁重,29Webpack,30.Browserify,31汇总,32或者其他的;安装页面为https://babeljs.io/docs/setup/#installation
所有主要的都有说明。
审查
JavaScript在过去几年中发生了巨大的变化,特别是2015年之后。未来还会继续变化。但是没有必要担心所有的新功能会过载;JavaScript始终是向后兼容的,所以没有必要采用新的特性,除非你已经准备好这样做并且需要它。
这些新特性涵盖了从允许在函数调用参数列表中添加逗号这样的小调整,到在标准库中添加新的方便方法,再到像声明式这样的重大改进类
语法(第4章),异步
函数(第9章)和模块(第13章)。
最终负责推动JavaScript向前发展的人是TC39 (Ecma International的第39技术委员会)的成员,该委员会由JavaScript开发人员、编程语言研究人员、库和大型网站作者、主要JavaScript引擎的代表以及JavaScript成功和未来的其他利益相关者组成。但任何人都可以参与其中。
开发新功能的过程是公开的。您可以通过各种GitHub存储库、发布的会议记录和TC39话语组跟踪进展并保持最新。此外,我继续报道这本书在书的网站上离开https://thenewtoys.dev
.
本书所涵盖的大多数特性都得到了尖端浏览器(如Chrome、Firefox、Safari和Edge)中的JavaScript引擎的支持,以及非浏览器环境中最近发布的引擎(如Node.js、Electron、React Native等)的支持。
像Internet Explorer这样的旧环境可以通过JavaScript-to-JavaScript编译(又名“编译”)来支持,使用可以集成到构建系统中的工具(如Babel)将旧式代码转换为新式代码。有些特性(比如你将在第14章学到的Proxy对象)不能完全通过这种方式得到支持,但是很多特性可以。
好的。舞台已经准备好了……
新玩具来了!
请注意
- 前身为欧洲计算机制造商协会(ECMA),但现在ECMA中只有E是该组织名称的大写字母。
http://www.ecma-international.org/memento/TC39.htm
https://tc39.es/ecma262/
https://www.electronjs.org/
https://reactnative.dev/
https://nodejs.org/
- 委员会也关心那些与网络没有直接关系的重要JavaScript代码。
https://tc39.es/ecma402/
https://ecma-international.org/memento/join.htm
https://github.com/tc39/ecma262
https://github.com/tc39/proposals
https://es.discourse.group/
https://tc39.es/process-document/
https://tc39.es/agreements/contributor/
https://github.com/tc39/test262
https://tc39.es/code-of-conduct/
- Discourse实例在很大程度上取代了非正式的讨论邮件列表。该列表仍然存在,但许多TC39代表建议避免使用它。
- 至少不恰当;它有一个不完整的let和const版本。
https://github.com/es-shims/es5-shim
https://github.com/zloirock/core-js
https://github.com/es-shims/
https://github.com/google/traceur-compiler
http://babeljs.io/
http://typescriptlang.org/
https://facebook.github.io/jsx/
https://reactjs.org/
https://babeljs.io/docs/en/babel-preset-env#docsNav
https://gulpjs.com/
https://gruntjs.com/
https://webpack.js.org/
http://browserify.org/
https://rollupjs.org/