让我们来看看JavaScript中一些有用的即将推出的功能。您将看到他们的语法,链接以及时了解他们的进度,我们将编写一个小型测试套件,以展示如何立即开始使用这些提案!
JavaScript是如何更新迭代的
如果您已经熟悉Ecma TC39委员会如何决定并处理JavaScript语言的变更,请随意跳过此部分。
对于我们其他对JavaScript编程语言如何发展感到好奇的人,我想快速概述一下这个过程。
JavaScript是一种名为ECMAScript的语言标准的实现,它被创建用于标准化语言的所有实现,因为它是在Web浏览器的早期发展而来的。
已经有八个版本的ECMAScript标准 ,有七个版本(第四版被放弃)。
每个JavaScript引擎开始实现每次发布后指定的更改。此图表将显示并非每个引擎都实现每个功能,并且某些引擎需要比其他引擎更长的时间来实现这些功能。虽然这可能看起来不是最佳的,但我相信它比没有标准更好!
建议
每个ECMAScript版本都经过审核提案的过程。如果提案被认为有用且向后兼容,则将包含在下一版中。
提案有五个阶段,在本文档中概述。每个提案都是最初提出的“strawman”或stage 0。在这个级别,他们要么尚未提交给技术委员会,要么尚未被拒绝,但仍未达到进入下一阶段的标准。
下面显示的提案都不属于第0阶段。
作为个人推荐,我想鼓励读者避免在生产应用程序中使用0阶段提案,直到它们处于不稳定的阶段。此建议的目的只是为了避免在提案被放弃或彻底更改时出现问题。
测试套件
编程功能的介绍通常会显示脱离上下文的代码段,或者使用这些功能来构建应用程序。由于我是TDD的忠实粉丝,我相信更好的方法来了解功能的作用是测试它。
我们将使用Jim Newkirk创造的学习测试来实现这一目标 _._,我们编写的测试将使断言不是关于我们自己的代码,而是关于编程语言本身。在学习第三方API或任何其他语言功能时,这个相同的概念非常有用。
Transpilers
如果您已熟悉转换器,请随意跳过此部分。
有些人可能想知道我们将如何使用尚未实现的语言功能!
JavaScript是一种不断发展的语言,它带有一些将JavaScript编译成JavaScript的转换器 。在表面上可能听起来不是很有帮助,但我向你保证!
它允许我们编写最新版本的JavaScript - 甚至包括0阶段提案 - 并且仍然能够在当今的运行时环境中执行它,如Web浏览器和Node.js.它通过将我们的代码更改为为旧版本的JavaScript编写而实现此目的。
Babel是最受欢迎的JavaScript转发器之一。我们将在马上使用它。
步骤
为此,您可以在新目录中运行以下命令:
npm init -f && npm i ava@1.0.0-beta.3 @babel/preset-env@7.0.0-beta.42 @babel/preset-stage-0@7.0.0-beta.42 @babel/register@7.0.0-beta.42 @babel/polyfill@7.0.0-beta.42 @babel/plugin-transform-runtime@7.0.0-beta.42 @babel/runtime@7.0.0-beta.42 --save-dev
然后,您需要将以下内容添加到package.json文件中:
"scripts": { "test": "ava"},"ava": { "require": [ "@babel/register", "@babel/polyfill" ] }
最后创建一个.babelrc文件:
{ "presets": [ ["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-stage-0" ], "plugins": [ "@babel/plugin-transform-runtime" ]}
现在你准备开始写一些测试了!
1.可选链接
在JavaScript中,我们一直在使用Objects。有时这些物体没有我们期望的确切形状。下面你会找到一个人为的数据对象示例 - 可能是从数据库或API调用中检索到的。
const data = { user: { address: { street: 'Pennsylvania Avenue', }, },};
哎呀,看起来这个用户没有完成注册:
const data = { user: {},};
假设,当我尝试访问应用程序仪表板上的街道时,我会收到以下错误:
console.log(data.user.address.street);
// Uncaught TypeError: Cannot read property 'street' of undefined
为避免这种情况,我们目前必须访问“street”属性,如下所示:
const street = data && data.user && data.user.address && data.user.address.street;console.log(street);
// undefined
在我看来,这种方法是:
- 不美观
- 繁重
- 啰嗦
这里是可选链接的地方。您可以像这样使用它:
console.log(data.user?.address?.street);
// undefined
那更容易,对吧?现在我们已经看到了这个功能的用处,我们可以继续深入研究。
所以我们来写一个测试!
现在我们看到可选链接保持了点符号的先前功能。接下来,让我们为不愉快的路径添加一个测试。
以下是可选链接如何用于数组属性访问:
有时我们不知道函数是否在Object中实现。
一个常见的例子是当您使用Web浏览器时。某些旧版浏览器可能没有某些功能。值得庆幸的是,我们可以使用可选链接来检测函数是否已实现!
如果链不完整,表达式将不会执行。在幕后,表达式大致转变为:
value == null ? value[some expression here]: undefined;
在可选链操作符之后没有什么?如果值未定义或为null,则将执行。我们可以在以下测试中看到该规则的实际应用:
有了它!可选链接减少了对if语句,lodash等导入库以及使用&&进行链接的需求。
一句警告: 您可能会注意到使用此可选链带来了一些最小的开销。您检查的每个级别?必须包含在引擎盖下的某种条件逻辑中。如果过度使用,将导致性能损失。当你收到或创建对象时,我建议使用它进行某种对象验证。这将限制对这些检查的需求,从而限制性能损失。
链接
这是该提案的链接。我也会在这篇文章的底部复制它,以便您可以在一个地方看到所有提案链接!
2. 空值合并
合并:融合或融合在一起
以下是我们在JavaScript中看到的一些常见操作:
- 检查未定义或空值
- Defaulting Values
- 确保0,false和空字符串不是默认值。
您可能已经看到它像这样:
value != null ? value : 'default value';
或者这样:
value || 'default value'
问题是,对于第二个实现,我们的第三个操作条件不满足。在这种情况下,数字零,布尔值false和空字符串都被视为false。这就是我们必须明确检查null和undefined的原因。
value != null
这与:
value !== null && value !== undefined
这就是新提案(无效合并)的用武之地。现在我们可以这样做:
value ?? 'default value';
这可以保护我们不会意外地默认那些虚假的值,但是仍然会在没有三元和!= null检查的情况下捕获null和undefined。
现在我们看到了语法,我们可以编写一个简单的测试来验证它是如何工作的。
您可以在测试中看到它使用null,undefined和void 0的默认值(计算结果为undefined)。它不会默认虚假值,如0,''和false。在这里查看GitHub。
3. 管道运算符
在函数式编程中,我们有一个术语“组合”,它是将多个函数调用链接在一起的行为。每个函数接收前一个函数的输出作为其输入。以下是我们在纯JavaScript中讨论的一个示例:
function doubleSay (str) { return str + ", " + str;}
function capitalize (str) { return str[0].toUpperCase() + str.substring(1);}
function exclaim (str) { return str + '!';}
let result = exclaim(capitalize(doubleSay("hello")));result //=> "Hello, hello!"
这种串联是如此常见,以至于组合函数存在于大多数功能库中,如lodash和ramda。
使用新的管道运算符,您可以跳过第三方库并按如下所示编写上述内容:
let result = "hello" |> doubleSay |> capitalize |> exclaim;result //=> "Hello, hello!"
目的是使_链_更具可读性。它也将在未来部分应用中很好地工作,或者现在它可以像这样实现:
let result = 1 |> (_ => Math.max(0, _));result //=> 1
let result = -5 |> (_ => Math.max(0, _));result //=> 0
现在我们看到了语法,我们可以开始编写测试了!
您可能注意到的一件事是,一旦将异步函数添加到管道,您必须等待该值。这是因为价值已成为承诺。有一些建议的更改支持|>等待asyncFunction,但尚未实现或决定。
好了,既然你已经看到了这些建议的实际应用,我希望你能够尝试一下这些建议!
学习测试的完整代码可以在这里找到。
以下是所有四个提案链接 :
tc39/proposal-optional-chaining _Contribute to proposal-optional-chaining development by creating an account on GitHub._github.com[](https://github.com/TC39/propo...
tc39/proposal-nullish-coalescing _proposal-nullish-coalescing - Nullish coalescing proposal x ?? y_github.com[](https://github.com/tc39/propo...
tc39/proposal-partial-application _proposal-partial-application - Proposal to add partial application to ECMAScript_github.com[](https://github.com/tc39/propo...
tc39/proposal-pipeline-operator _proposal-pipeline-operator - A proposal for adding the simple-but-useful pipeline operator to JavaScript._github.com[](https://github.com/tc39/propo...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。