2

让我们来看看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转发器之一。我们将在马上使用它。

步骤

您需要安装Node.jsNPM

为此,您可以在新目录中运行以下命令:

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

在我看来,这种方法是:

  1. 不美观
  2. 繁重
  3. 啰嗦

这里是可选链接的地方。您可以像这样使用它:

console.log(data.user?.address?.street);
// undefined

那更容易,对吧?现在我们已经看到了这个功能的用处,我们可以继续深入研究。

所以我们来写一个测试!

现在我们看到可选链接保持了点符号的先前功能。接下来,让我们为不愉快的路径添加一个测试。

以下是可选链接如何用于数组属性访问:

有时我们不知道函数是否在Object中实现。

一个常见的例子是当您使用Web浏览器时。某些旧版浏览器可能没有某些功能。值得庆幸的是,我们可以使用可选链接来检测函数是否已实现!

如果链不完整,表达式将不会执行。在幕后,表达式大致转变为:

value == null ? value[some expression here]: undefined;

在可选链操作符之后没有什么?如果值未定义或为null,则将执行。我们可以在以下测试中看到该规则的实际应用:

有了它!可选链接减少了对if语句,lodash等导入库以及使用&&进行链接的需求。

一句警告: 您可能会注意到使用此可选链带来了一些最小的开销。您检查的每个级别?必须包含在引擎盖下的某种条件逻辑中。如果过度使用,将导致性能损失。当你收到或创建对象时,我建议使用它进行某种对象验证。这将限制对这些检查的需求,从而限制性能损失。

链接

这是该提案的链接。我也会在这篇文章的底部复制它,以便您可以在一个地方看到所有提案链接!

2. 空值合并

合并:融合或融合在一起

以下是我们在JavaScript中看到的一些常见操作:

  1. 检查未定义或空值
  2. Defaulting Values
  3. 确保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!"

这种串联是如此常见,以至于组合函数存在于大多数功能库中,如lodashramda

使用新的管道运算符,您可以跳过第三方库并按如下所示编写上述内容:

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...


_小生_
2.6k 声望1.1k 粉丝

人一般不会因为做过什么而后悔,