2016 年 8 月

第 31 卷,第 8 期

此文章由机器翻译。

工作的程序员如何成为平均: 探究 ECMAScript

通过 Ted Neward |2016 年 8 月

Ted Neward欢迎回来,MEANers。

我们中间 2016年。什么您可能并未意识到是该 JavaScript (它实际上正式称作 ECMAScript) 都有新版本的语言的不同,ECMAScript 2015。如果您的 JavaScript 代码不开始使用它,那么很长时间来启动。幸运的是,它是轻松地这样做,因为有充分的理由这样做。在本期中,我将回顾一下其中一些 ECMAScript 2015,更有趣和重要功能,并在将来的块中,我将介绍一下什么就好像在更现代的样式中使用平均值 (实质上,既然您已获得对如何平均坚定的初步知识应用程序的操作,我将完全重新启动基本代码; 详细说明,然后)。

简单的更改

某些语言最简单的更改只需接受一段时间以来已广泛生态系统和社区中的约定的编程模式。

这些约定之一是声明的,不变性,ECMAScript 2015 体现通过使用常量:

const firstName = "Ted";

此操作,请像 c + + 声明具有相同名称的声明的引用名称 ("firstName") 可以永远不会指向任何地方;它不要求对引用所指向的对象不能更改。ECMAScript 2015 还具有可变的引用声明的新窗体,但让,即实质上是顺便代替 var;我建议采用在有任何机会。

更多"便利"的类型更改,若要添加到使用 backticks (左移探单引号,通常在美式键盘上颚化符下方会显示) 而不单引号或双引号的语言字符串插值︰

const speaker = { name: "Brian Randell", rating: 5 };
console.log(`Speaker ${speaker.name} got a rating of ${speaker.rating}`);

C# 之类的样式字符串插值,尝试将其转换为一个字符串,并将其插入生成的字符串,ECMAScript 2015 将解释的大括号内的表达式。

语言更重要的更改之一已被接受"块范围";以前,在 JavaScript 中,变量作用域为函数,不向任意代码块。这意味着在函数内任意位置声明的任何变量是可在整个函数,而不仅仅是在其中声明它时,这是令人困惑细微错误的源块整个。

有趣的此块范围的副作用是 ECMAScript 现在获得局部声明的函数,类似于 C# 7 个建议︰

{
  function foo () { return 1 }
  foo() === 1
  {
    function foo () { return 2 }
    foo() === 2
  }
  foo() === 1
}

在这里,我定义在块中,返回值 1 函数 foo。然后,没有特定的原因,我引入了一个新范围块、 定义新的 foo,以及演示,当该作用域块将关闭,foo 的定义将返回到以前的版本 — — 这正是这个世界上的几乎所有其他语言完成已。

但是,习惯于,ECMAScript 不使用本地嵌套的函数;相反,它更适合于创建一个更函数式风格编程惯例,定义一个变量的引用要指向的匿名函数定义,并使用它。支持,ECMAScript 2015 现在支持将箭头函数,使用与 C# 几乎完全相同的语法︰

const nums = [1, 2, 3, 4, 5];
nums.forEach(v => {
  if (v % 2 == 0)
    console.log(v);
});

(请记住以前的 ECMAScript 标准的一部分,作为函数 forEach 向数组添加。) 这将因为假定,输出数组中的偶数。如果另一方面,我想要构造偶数源阵列外,我可以使用内置"映射"和箭头函数来执行实质上是相同的操作︰

const nums = [1, 2, 3, 4, 5];
const evens = nums.map(v => v * 2);

箭头函数期待已久的更改也是合理预期,大多数基于 JavaScript 的代码将采用这些主动的方式。

承诺

通过 ECMAScript 社区来帮助解决的一些围绕 Node.js 回调的编程样式复杂性浮动的许多解决方案,其中一个重复主题时,"约定"— 实质上,基于库的方法,将回调转换到的内容所示更串行性质。几个不同的基于约定的库已在社区内常用和 ECMAScript 委员会最终选择标准化对一,它现在只需将称为"承诺。"(请注意大写的名称中; 这也是用于实现它们的主体对象的名称。) 使用 ECMAScript 2015 承诺可以的看有些怪在第一次,与标准的同步编程,但大多数情况下,它相比有意义。

请考虑一下,想要调用某个约定用于能够执行一些在后台的库例程的应用程序代码︰

msgAfterTimeout("Foo", 100).then(() =>
  msgAfterTimeout("Bar", 200);
).then(() => {
  console.log(`done after 300ms`);
});

在这里,其理念是将该 msgAfterTimeout 100 毫秒超时之后,打印"Hello,Foo"并之后,再次执行相同的操作 ("Hello,栏"200 毫秒之后),并且之后,只需将消息输出到控制台。请注意如何步骤使用连接,则函数调用 — 从 msgAfterTimeout 返回的对象是一个承诺对象,然后定义了初始承诺完成执行时调用的函数。本部分说明名称 — 承诺对象为,实际上,都在宣传时要调用然后函数的初始代码完成。(此外,会发生什么情况从函数中引发的异常? 承诺允许您指定在此情况下,执行的函数使用 catch 方法)。

在你想要同时运行多个函数,然后在全部完成后,才执行一个函数的情况下,您可以使用 Promise.all:

const fetchPromised = (url, timeout) => { /* ... */ }
Promise.all([
  fetchPromised("http://backend/foo.txt", 500),
  fetchPromised("http://backend/bar.txt", 500),
  fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
  let [ foo, bar, baz ] = data;
  console.log(`success: foo=${foo} bar=${bar} baz=${baz}`);
}, (err) => {
  console.log(`error: ${err}`);
});

如您所见,将收集以异步方式执行的每个函数的结果,并将其组合成一个数组,然后传递给 (第一个) 然后赋予函数作为第一个参数中。(让的语句是举例说明如何在 ECMAScript 2015 中,另一项新功能的"重构分配",从根本上来说,每个元素的数据数组分配给每个这些三个声明的变量和其余部分中,如果有的话,被丢弃。) 请注意,,,则传递的事件中执行任何异步函数中没有错误,使用第二个函数。

肯定是不同的样式的编程中,但不是寻常的任何人员所用的时间正在与各种 C# 异步机制,按照 PLINQ 或 TPL。

ECMAScript 2015 已承诺之外到标准库 (后者所有 ECMAScript 环境都应该提供,无论它们浏览器或服务器) 添加几个重要的事情。特别是,他们已添加的映射 (键/值存储,类似于 < K,V >.NET 字典类型) 和一组 (一个无重复"包"的值),这两个可用而无需任何种类的导入︰

const m = new Map();
m.set("Brian", 5);
m.set("Rachel", 5);
console.log(`Brian scored a ${m.get("Brian")} on his talk`);
const s = new Set();
s.add("one");
s.add("one"); // duplicate
s.add("one"); // duplicate
console.log(`s holds ${s.size} elements`);
  // Prints "1"

此外,对各种对象原型已在 ECMAScript 环境中,如发现在阵列上,以及一些数字评估方法 (如 isNAN 或 isFinite) 到数字的原型是要添加几个更多标准函数。大多数情况下,这些以及更早的映射和组类型已经存在社区中作为第三方程序包,但是中导入到标准的 ECMAScript 库可帮助减少了一些导致 ECMAScript 横向程序包的依赖关系。

模块

可能的最重大更改之一至少从构建一个平均值基于应用程序的角度来看,是采用的正式模块系统。以前,正如我几乎年前,平均值基于应用程序都使用 Node.js 需要另一个 JavaScript 文件的函数"import"(解释/执行),并返回一个对象供使用。这意味着,当平均开发人员编写了以下行的 express 对象返回通过计算存储在内部通过使用 npm 安装的 node_modules 子目录中的 JavaScript 文件︰

var express = require('express');

若要使这项工作,多个约定必须已到位,和它已生效,但正规缺乏完全受阻的语言和生态系统的向前推进。ECMAScript 2015 中引入了新的关键字进行形式化大部分内容。

它是有点循环的解释,因此让我们来举一个简单的示例︰ 两个文件、 一个调用的 app.js 和它想要使用的库调用数学。数学库将非 npm 库 (为简单起见),并且将具有此命令将导出的两个值︰ pi (3.14) 的值调用 PI 和一个函数来计算总的数字,数组名为之和︰

//  lib/math.js
export function sum (x, y) { return x + y };
export var pi = 3.141593;
//  app.js
import * as math from "lib/math";
console.log("2PI = " + math.sum(math.pi, math.pi));

请注意,在库进行客户端可以访问符号声明使用"导出"关键字,并且引用库,当您使用的关键字"导入。" 更常见,但是,你想要导入符号从库中作为顶级元素本身 (而不是作为其成员),因此更常见的用法可能会这样︰

//  app.js
import {sum, pi} from "lib/math"
console.log("2π = " + sum(pi, pi));

这种方式,可以使用导入的元件,直接,而不是其成员作用域的窗体中。

总结

标准; 是极具 ECMAScript 2015 中隐藏读者还没有看到任何这些功能以前现在应明确签出 (不断增长的列表) 的任何资料介绍了新的标准在 Internet 上找到。官方 ECMA 标准位于 bit.ly/1xxQKpl (它列出当前为第七版,这主要是因为 ECMA 决定对该语言的新更改,请转到每年的节奏调用 ECMAScript 2016 规范)。但是,有关的更少"正式"说明的语言,读者都应当先签出 es6-features.org,它提供的新语言功能和新增功能之前已存在语言中其比较的列表。

此外,Node.js 几乎完全符合 ECMAScript 2015 的功能集时,其他不是,或环境处于各种状态的支持。对于这些环境中,不是很多达完整级别的支持,有两个"transpiler"工具 — Google 赞助 Traceur 编译器和 Babel 编译器。(两者都是,当然,只需 npm 消失。) 当然,Microsoft 的 TypeScript 是令人惊异接近 ECMAScript 2015 最终会被,意味着一个无法立即采用 TypeScript 并且几乎是行的行符合 ECMAScript 2015 时将转换为 ECMAScript 2015 是所需或不适合。

所有这些功能将变得更加明显,因为您开始使用平均工具,可使使用它们,因此不施加压力现在如果它们尚没有任何意义。同时...祝您编码愉快 !


Ted Neward 是基于西雅图的 polytechnology 顾问、 发言人和导师。 他曾写过 100 多篇文章,是 F # MVP 和具有创作,并且与人合著过十几本书。如果您有兴趣请他参与您的团队工作,请通过 ted@tedneward.com 与他联系,或通过 blogs.tedneward.com 访问其博客。

感谢以下技术专家对本文的审阅: Shawn Wildermuth