JS规范又双叒要更新了

2019 年 6 月 28 日 前端之巅

作者|Jae Sung Park
译者 | 王强
编辑|Yonie

JavaScript 目前依然大受欢迎。如 GitHub 报告 Octoverse 中的图表所示,JavaScript 是 GitHub 多年来最常用的语言。此外,Stack Overflow 最近的“2019 开发者调查报告”也将 JavaScript 列为最受欢迎的技术。

GitHub 最流行语言的变迁

ECMAScript 2015 和随后的 ECMAScript 规范看起来也被众多开发者顺利接受了。

“2018 年 JS 现状”中的 JavaScript 偏好:https://2018.stateofjs.com/javascript-flavors/overview/

本文将介绍 ECMAScript 2018 的主要功能,以及预计将包含在 ECMAScript 2019 和 2020 规范中的提案。

相关链接:

GitHub 报告 Octoverse 中的图表: https://octoverse.github.com/projects#languages

Stack Overflow 2019 开发者调查报告: https://insights.stackoverflow.com/survey/2019#technology

备注:本文的内容基于截止 2019 年 6 月的已知信息。文章中的内容和事实可能会随时间推移发生变化。

一些改动和新闻

有些改变不会对 JavaScript 的语言层面产生直接影响,但可能会带来间接影响,例如影响环境和生态系统等。

TC39 的变化

TC39 是一个讨论 JavaScript 标准规范的技术委员会,已决定从 2019 年开始改变其运营结构。TC39 每年召开六次会议,规模已经发展到每次有 40 到 60 人参会的程度。

这个委员会以前是主席和副主席的运营结构,现在改为由三位联合主席(Aki Braun(PayPal)、Brian Terlson(微软)和 Yulia Startsev(Mozilla))共同负责的架构。他们还在 2019 年 3 月开设了官方网站: https://tc39.github.io

在 TC39 联合主席 Aki Braun 撰写的文章“TC39 的一年(多)历程”中介绍了 TC39 会议的进展和成果。

2018 年 7 月初,npm 加入了 ECMA International 和 TC39。

相关链接:

ECMA International: https://www.ecma-international.org/

TC39: https://blog.npmjs.org/post/175722319045/npm-joins-ecma-international-and-tc39

SharedArrayBuffer

受 Meltdown 和 Spectre 安全漏洞影响,浏览器厂商已更改其默认设置,禁用了自 2018 年 1 月 5 日起使用的 SharedArrayBuffer 对象。

除 Chrome 之外,其他浏览器依旧保持着这种设置。Chrome 67 版之后通过站点隔离重新激活了该对象,详情请参阅: https://bugs.chromium.org/p/chromium/issues/detail?id=821270

相关链接:

Meltdown 和 Spectre 安全漏洞: https://meltdownattack.com/

站点隔离: https://www.chromium.org/Home/chromium-security/site-isolation

微软 Edge 改用 chromium 引擎

2018 年 12 月 6 日,微软宣布将其 Edge 浏览器转向 Chromium 引擎,震惊业界。

在 2019 年 1 月 29 日举行的 TC39 会议期间,场下的微软问答环节针对 Edge 的引擎转换披露了以下事实:

  • 没有开源旧引擎的计划。

  • 现有 JavaScript 引擎 ChakraCore 将继续更新,但没有长期更新计划。

ChakraCore 团队成员 Limin Zhu 评论说:除了浏览器,还有很多项目在使用 ChakraCore。因此尽管 Edge 改变了方向,我们的团队仍将继续支持 ChakraCore。

可以从微软 Edge 内部通道站点下载基于 chromium 的 Edge(Canary/Dev/Beta 版本): https://www.microsoftedgeinsider.com/en-us/download/

微软将 Edge 转向 Chromium 引擎的目的和未来计划,可参阅文章“微软 Edge 与开源 Chromium:我们的意图”: https://github.com/MicrosoftEdge/MSEdge/blob/master/README.md

从开发者的角度来看,微软 Edge 的这种转变可以减轻跨浏览器开发的负担和困难。

但是从 Web 生态系统的角度来看,此举可能会带来令人担忧的结果。因为这会减少浏览器的多样性。

你可能还记得 Internet Explorer 处于垄断地位的时代,当时许多网站只支持 Internet Explorer;类似地,基于 chromium 的浏览器越来越多也不是什么好事情。

有关多样性的担忧,请参阅文章“Chrome 正在变成新的 Internet Explorer 6“和 Mozilla 的“再见,EdgeHTML”(文章链接见下方)。

相关链接:

Chrome 正在变成新的 Internet Explorer 6: https://www.theverge.com/2018/1/4/16805216/google-chrome-only-sites-internet-explorer-6-web-standards

Mozilla 的“再见,EdgeHTML”: https://blog.mozilla.org/blog/2018/12/06/goodbye-edge/

模块支持

ECMAScript 2015 引入了模块支持,现在模块作为基本功能已经广泛应用。

接下来看看动态 import() 语法和原生模块支持的概况与当前状态,进一步扩展模块的应用范围。

动态 import()

基于 Promise 的 import() 语法可以动态加载模块。之前该提案在第 3 阶段停留了一阵儿,但最终于 6 月 6 日达到“第 4 阶段”并进入 ECMAScript 2020 规范。

  • 有关 import() 语法的详细说明,请参阅文章“ES 模块,深入图解”: https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/

  • 有关浏览器支持范围请参阅: https://caniuse.com/#feat=es6-module-dynamic-import

import("./myModule.mjs")  
.then(module => {
...
});
// using async/await
(async () => {
const module = await import("./myModule.mjs");
...
})();

Firefox 从 60 版开始可以设置 javascript.options.dynamicImport 标志(flag)来使用 import() 语法,Firefox 67 开始默认启用该设置。

微软 Edge(旧引擎版本)尚不支持 import() 语法,但是基于 chrome 的 Edge 发布时可能会提供支持。

原生模块加载

从 2018 年 5 月发布的 Firefox 60 开始,Firefox 可以无需标志就使用原生模块(ESM)。2017 年 9 月发布的 Node.js 8.5.0 实验性地支持 ESM。

Node.js 中的 ESM 需要 --experimental-modules 标志,如下例所示。在这种情况下,CommonJS 的'request()'将被禁用以加载模块,请参阅文章“新的 experimental-modules 发布”: https://github.com/nodejs/modules/blob/master/doc/announcement.md

node --experimental-modules my-app.mjs

Node.js 基金会为提供 ESM 的官方支持组建了“模块团队”: https://github.com/nodejs/modules

模块团队的工作分为 4 个阶段:

  • 阶段 1: 从当前 Node 分支,但删除了 Node 8.5.0 之后版本中的大部分 --experimental-modules 实现。

  • 阶段 2: 添加“最小内核”,凡是工作组认为会在新的 ES 模块实现中出现的模块都会包含进去。

  • 阶段 3: 在实现中加入足够多的功能,这些功能应该对主流用户有益,从而构建出最小可行产品。

  • 阶段 4: 改善用户体验并扩展 MVP。

这项工作目前正处于第 3 阶段,详情请查看: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md#phase-3-path-to-stability-removing---experimental-modules-flag

ECMAScript 2018

ECMAScript 2018于 2018 年 6 月宣布,Github 地址: http://www.ecma-international.org/ecma-262/9.0/

异步迭代器

异步运算符枚举异步流数据,其操作类似于典型的运算符,并使用语法形式 for — await — of。异步运算符和普通运算符之间的区别在于前者返回的是 Promise 对象。

async function test() {  
// Regular Iterator
for (const i of list) ...
// Async Iterator
for await (const i of asyncList) ...
}

处理异步调用流时可以创建异步运算符工厂。

// example from: https://jakearchibald.com/2017/async-iterators-and-generators/
async function* asyncRandomNumbers() {
const url = "https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain&rnd=new";
while (true) {
const response = await fetch(url);
const text = await response.text();
yield Number(text);
}
}
(async function() {
let i = 0;
for await (const number of asyncRandomNumbers()) {
console.log(++i, "=>", number);
if (i === 10) break;
}
})();
// 1 "=>" 65
// 2 "=>" 62
// ...
对象 Rest/Spread 属性

与 ECMAScript 2015 中的 Rest 参数和 Spread 运算符规范一样,此提案引入了对象字面量(literal)的对象解析分配和传播属性。

// Rest property
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }
// Spread property
let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }
删除模板字面量语法限制

模板字面量删除了对转义序列使用的限制。

标记模板字面量是接收模板并返回修改后的字符串的函数。传递给函数的字符串可以是以下类型之一:

  • Cooked:转义序列已被解释。

  • Raw:转义序列是普通文本。模板字符串中的非解释值由 String.raw() 方法处理。

function tagFunc(str, substs) {  
return str;
}
const result = tagFunc`\u{4B}`;
result; // ["K"]
result.raw; // ["\u{4B}"]

以前,如果模板在反斜杠后有一些字符序列会被视为非法,并且不返回原始字符串。

  • \u:Unicode(例如\u004B)

  • \x:十六进制(例如\x4B)

  • \positive:八进制(例如\141)

ECMAScript 2018 移除了与转义序列相关的所有语法限制,并以原始形式返回字符串。在这种情况下,解释的值返回 undefined。

const result = tagFunc`\131`;  
result; // [undefined]
result.raw; // ["\131"]

了解有关模板字面量的问题和解决方案的更多信息: http://2ality.com/2016/09/template-literal-revision.html

Promise.prototype.finally

与 try...catch 语句的 finally 语法一样,此提案引入了对 Promise 对象的类似用法。

finally 语法是在最后无条件执行的代码块,与 Promise 对象的处理状态('resolve'或'reject')无关。调用 Promise 对象后,无论结果如何都将执行此代码块。

let isLoading = true;
fetch("https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain&rnd=new")
.then(function(res) {
if(res) {
return res.text();
}
throw new TypeError("Error");
})
.then(function(text) { /* Success */ })
.catch(function(error) { /* Error */ })
.finally(function() {
// will be performed regardless success or error
isLoading = false;
});

查看 MDN 的 Promise.prototype.finally 文档了解更多信息: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

正则表达式

新增了几个正则表达式提案。

  • 正则表达式的 s 标志:点(.)能匹配所有字符,但\r 和\n 是例外。为了解决这个问题引入了新的 s 标志。

// previous
/./test("a"); // true
/./.test("\n"); // false
// dotAll flag
/./s.test("\n"); // true
  • RegEx 命名捕获组:它可以命名一个捕获组。(?<name>pattern) 将 添加到捕获组模式,然后使用该名称作为捕获的引用。

const rx = /(?<year>[0-9]{4})-(?<month>[0-9]{2})/;  
const match = rx.exec('2018-03');
match.groups.year; // 2018
match.groups.month; // 03
  • RegExp Lookbehind 断言:在正则表达式中,一个模式的值由字符串跟随(先行)或不跟随(负向先行)。相比之下,这个提案提供了寻找特定模式以前进(后行)或不前进(负向后行)的能力。

// positive lookahead
/aa(?=bb)/.test("aabb"); // true
// negative lookahead
/aa(?!bb)/.test("aac"); // true
// positive lookbehind
/(?<=aa)bb/.test("aabb"); // true
// negative lookbehind
/(?<!=aa)bb/.test("bbbb"); // true

  • RegEx Unicode 属性转义。Unicode 属性转义是在设置了 u 标志的正则表达式中新增的可用转义序列类型。

/^\p{White_Space}+$/u.test('\t \n\r');  // true /^\p{Script=Greek}+$/u.test('μετά');  // true
ECMAScript 2019

ECMAScript 2019 尚处于候选草案状态。根据之前版本的发布日期推算,2019 最终版本预计将在 2019 年 6 月左右公布。

Array.prototype.flat()/ Array.prototype.flatMap()

Array.prototype.flat()方法和Array.prototype.flatMap()方法以递归方式查找指定深度的子数组元素,并创建一个连接到其中的新数组。

// Array.prototype.flat
[1, 2, [3, 4]].flat(); // [1, 2, 3, 4]
[1, 2, [3, 4, [5, 6]]].flat(1); // [1, 2, 3, 4, [5, 6]]
// Array.prototype.flatMap
[1, 2, 3, 4].map(x => [x * 2]); // [[2], [4], [6], [8]]
[1, 2, 3, 4].flatMap(x => [x * 2]); // [2, 4, 6, 8]

关于 .flat() 命名的小故事:

最初使用的名称是“.flatten()”。但是,MoTools(一个应用广泛的遗留库)有一个类似的名称“array.prototype.flatten()”,提供了类似的功能。如果继续使用“.flatten()”,可能会在使用 MoTools 的网站上出问题。

为了避免潜在的冲突,.flatten() 被改名为 .flat()。此外“.smoosh()“也是候选之一;还有人建议改变 ECMAScript 2019 中 MoTools 的 flatten() 行为。但这可能让许多不再更新的网站崩溃,Tom Dale 的 Twitter 中指出了这一点(他参与了 Ember 和 SproutCore 的开发)。

Object.fromEntries()

Object.fromEntries() 将键值对列表转换为对象。

const entries = new Map([  
['foo', 'bar'],
['baz', 42]
]);
Object.fromEntries(entries); // { foo: "bar", baz: 42 }
String.prototype.trimStart()/ .trimEnd()

删除字符串开头的空格(.trimLeft()),或删除字符串末尾的空格(.trimRight())。

const greeting = "   Hello world!   ";
greeting.trimStart(); // "Hello world! "
greeting.trimEnd(); // " Hello world!"
Symbol.prototype.description 属性

Symbol.prototype.description 属性返回 Symbol 对象的可选只读描述。

// will return 'Test Description'
Symbol("Test Description").description;
可选的 catch 绑定

可选的 catch 绑定提案是说,如果 try...catch 语句中的 catch 语法中未使用参数,则允许省略参数。

可选的 catch 绑定提案: https://github.com/tc39/proposal-optional-catch-binding

// Traditional way
try { ··· } catch(e) { ··· }
// Optional catch binding
// if don't need the use of parameter, it can be omitted
try { ··· } catch { ··· }
Array.prototype.sort() 稳定性

当对具有 10 个以上元素的数组排序时,Array.prototype.sort() 方法使用了不稳定的快速排序算法。为了确保数组正确对齐,ECMAScript 2019 对 Array.prototype.short() 使用了 Timsort 算法。详情清查看: https://en.wikipedia.org/wiki/Timsort

此规范目前适用于所有 JavaScript 引擎。但基于 ChakraCore 的微软 Edge 对包含超过 512 个元素的数组会出现排序错误。

下面的截图显示了 Edge 和 Firefox 上的稳定性测试结果。如图所示,Edge 出错了。

稳定性测试结果:(左)Edge 17.17134/(右)Firefox 66.0.2

更多详细内容请参阅: https://docs.google.com/presentation/d/1mHvxDciqsAchhjepMZlU5fn1DBvglCXSjDWUEtsPGvI/edit#slide=id.g41da6c5107_0_0

格式良好的 JSON.stringify

RFC 8259 指定要编码为 UTF-8 格式的 JSON 文本用于 JSON 对象数据交换。但是当使用 JSON.stringify() 时,一些 UTF-16 代码(从 0xD800 到 0xDFFFF 的字符被归类为“代理”)不会编码为 UTF-8。

RFC 8259: https://tools.ietf.org/html/rfc8259#section-8.1

ECMAScript 2019 会返回一个转义序列,而不是返回一个无效的、Unicode 字符串,如下图所示(Edge)。

Edge 和 Firefox 上的 JSON.stringify() 结果

更多详细信息请查看提案文档: https://github.com/tc39/proposal-well-formed-stringify

包含 JSON

ECMAScript 声明 JSON 是 JSON.parse 的一个子集,但事实并非如此,因为 JSON 字符串可以包含未转义的 U+2028 LINE SEPARATOR 和 U+2029 PARAGRAPH SEPARATOR 字符。

该提案建议扩展 ECMA-262,允许这些字符不将 JSON 分解为 ECMAScript 的子集。

// if ECMA is superset of JSON, these must be true
eval('"\u2028"') === "\u2028" // true
eval('"\u2029"') === "\u2029" // true

更多详细信息请查看提案文档: https://github.com/tc39/proposal-json-superset

Function.prototype.toString 修订

根据 ECMAScript 2016 中的定义,Function.prototype.toString() 的结果可能因引擎而异。ECMAScript 2019 确保返回定义的原始代码。详情请查看: https://tc39.es/Function-prototype-toString-revision/

返回函数中定义的代码时,ECMAScript 2019 使用以下算法返回函数中定义的代码字符串:

  • 换行符:\r\n(Windows)或\n(macOS)都以 Unix 样式返回\n。

  • 内置函数: 未通过 ECMAScript 定义的所有代码(主要是内置函数)将作为 [native code] 返回。

isNaN.toString();  // "function isNaN() { [native code] }"

不同浏览器中“isNaN.toString()”的结果:

  • 通过 Function 和 GeneratorFunction 动态创建的函数: 引擎必须创建适当的源代码并将其附加到函数上。

  • 其他情况下: 抛出 TypeError。

更多详细信息请查看: http://2ality.com/2016/08/function-prototype-tostring.html

ECMAScript 2020

截至 2019 年 3 月 1 日,TC39 repo master 分支已升级为 ECMAScript 2020。详情请参阅: https://github.com/tc39/ecma262/commit/7a9a9b6b25c115fcda95e943e8875432636f2cfd

此时,ECMAScript 2020 中已完成的提案(阶段 4)只有 String.prototype.matchAll() 和 import(),但将来完成提案的列表会加入更多项目。

String.prototype.matchAll()方法与String.prototype.match()的工作方式类似。前者与 g(global)/y(sticky) 标志一起使用时,返回包含匹配字符串和匹配详细信息的迭代器。

const str = "test1test2";  
const rx = /t(e)(st(\d?))/g;
str.match(rx); // ["test1", "test2"]
for (const match of str.matchAll(rx)) {
// 1: ["test1", "e", "st1", "1", index: 0, input: "test1test2"]
// 2: ["test2", "e", "st2", "2", index: 5, input: "test1test2"]
match;
}
一些新的或未完成的提案

下面来看一些尚未进入最后阶段的有趣提案。

globalThis

通常,访问顶级对象要通过浏览器环境中的“window”对象。

作为执行环境的扩展,新提案中访问顶级对象的方式也发生了变化。

  • 在 Node.js 环境中,通过“global”对象访问顶级对象。

  • HTML5 规范有“Window”和“WindowProxy”,而 ECMAScript 2015 规范中这两个对象都能用来访问顶级对象。

了解 Window 和 WindowProxy 对象的差异: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Inner_and_outer_windows

以下代码是在所有环境下获取顶级对象(“global”)引用的最简单方法。但是这种方法会导致 Chrome 应用中的内容安全政策(CSP)违规。详情请参阅: https://github.com/paulmillr/es6-shim/issues/301

var global = Function('return this')();

知名的 ES6 兼容 shim 库——ES6 shim,使用下面的函数来获取全局对象,这是目前常用且最好的方法。

ES6 shim: https://github.com/paulmillr/es6-shim

// https://github.com/paulmillr/es6-shim/blob/003ee5d15ec1b05ae2ad5ddad3c02fcf8c266e2c/es6-shim.js#L176
var getGlobal = function () {
/* global self, window, global */
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};

新提案“globalThis”提供了访问顶级对象的方法,摆脱了与环境的关联性。该提案目前处于第 3 阶段,尚未最终确定。但在 Chrome 71 和 Firefox 65 以及 Node.js 12 中,globalThis 对象可以按如下方式使用:

globalThis.setTimeout;  // window.setTimeout

关于“globalThis”这个名字:

与“Array.prototype.flat()”案例类似,这个提案一开始命名为“global”。但是使用这个名称会让 flickr.com 崩溃,所以就改为“globalThis”了。

类字段声明

Babel 7.1.0(2018 年 9 月 17 日发布)版本开始可以使用类字段声明。但这个提案尚未达到最后阶段,此时仍处于“第 3 阶段”。

该提案以更直观,更简单的方式为类变量引入了声明性语法。

  • 初始化(Initialization): 通过构造函数初始化实例变量。

class MyClass {  
constructor() {
this.x = 1;
this.y = 2;
}
}

例变量可以使用类字段定义为以下代码的 //Initializer 部分,初始化区域在构造函数运行之前运行。

class MyClass {  
// Initializer
x = 1;
y = 2;
log = console.log("Initializer");
constructor() {
console.log("Constructor:", this.x, this.y);
}
}
new MyClass();
// Initializer
// Constructor: 1 2
  • 私有声明(private declaration):以前 JavaScript 没有提供声明“private”的方式,许多开发者使用下划线(“_”)前缀作为约定。但这并不能真正实现私有化(不过的确有一种方法让变量或方法私有化运行)。

function MyClass() {  
this._x = 1;
this._y = 2;
}
MyClass.prototype.getX = function() {
return this._x;
}

私有声明器使用数字符号(#)作为前缀来明确声明它是私有的。以“#”开头的变量或方法只能在类块中访问。

class MyClass {  
#foo; // private field
constructor(foo) {
this.#foo = foo;
}
incFoo() {
this.#foo++;
}
}
  • 声明和访问:以下是以各种形式的声明和访问类字段的简单示例。

class MyClass {  
A = 1; // (a) instance field
static B = 2; // (b) static class field
#C = 3; // (c) private field
getPrivate() {
return this.#C;
}
}
new MyClass().A; // 1
MyClass.B; // 2
new MyClass().getPrivate(); // 3

更多详细信息请查看: http://2ality.com/2017/07/class-fields.html

内置模块

内置模块规范现在处于“第 1 阶段”,与 ESM 一样。与通常 ESM 的不同之处在于它们是“内置的”,并随浏览器本身一起分发。

内置模块不直接对全局暴露。它们仅通过导入语法可用。如果浏览器支持内置模块,则使用“std:”前缀 + 模块名称导入这些模块,如下所示。此示例中加载的是 KV Storage 模块: https://wicg.github.io/kv-storage/

import {storage, StorageArea} from "std:kv-storage";

KV Storage 模块和导入映射提案与内置模块规范密切相关。它们俩不属于 ECMAScript 规范,而属于 WICG。

KV Storage 模块:Chrome 74 增加了第一个内置模块 KV Storage。KV Storage 解决了 localStorage 的性能问题,并继承了简单 API 的优势。

  • 在 Chrome 74 中,可以使用 chrome://flags/#enable-experimental-web-platform-features 标志启用 KV Storage。

  • 请参阅“内置模块演示”页面中的 KV Storage 演示: https://rollup-built-in-modules.glitch.me/

KV Storage 具有与 Map 对象类似的 API。字符串和可序列化数据类型可用作键值。它返回一个 Promise 或 Async 迭代器,它们会被异步处理。

两个命名导出分别是storage和StorageArea:

  • storage:是 StorageArea 类的实例,名称为 default(默认存储数据库为“kv-storage:default”)。

  • StorageArea:适用于需要额外隔离的情况(例如,存储数据并希望避免与通过默认的 storage 实例存储的数据冲突的第三方库)。StorageArea 数据存储在名为 kv-storage:$ {name} 的 IndexedDB 数据库中,其中名称是 StorageArea 实例的名称。

import {storage} from "std:kv-storage";
const main = async () => {
const oldPreferences = await storage.get("preferences");
document.querySelector("form")
.addEventListener("submit", async () => {
const newPreferences = Object.assign({}, oldPreferences, {
// Updated preferences go here...
});
await storage.set("preferences", newPreferences);
});
};
main();

导入映射: 导入映射提案允许控制 JavaScript import 语句和 import() 表达式获取的 URL,并允许在非导入上下文中复用此映射。

导入映射为内置模块提供 Polyfill 和回落,使它们能够将当前不可用的模块标识符映射到 URL 上。详情请参阅: https://docs.google.com/document/d/1vFQzbmxg9ilpg8CT_P8roEYcpTfZ06Q5N4J9-ZQqqZo/edit

例如,内置模块 KV Storage 目前仅在 Chrome 中可用。在支持的浏览器中不会出现加载问题,但对于没有提供支持的浏览器来说,就需要加载 KV Storage 的 polyfill 了。

以下示例介绍了导入映射的用法。定义模块的映射并使用 import 语句的关键 URL 值。

在没有提供支持的浏览器中,导入 URL 被识别后作为普通导入 URL 处理。如果浏览器提供了支持,它们将根据映射信息流动。

<!-- The import map is inlined into your page -->  
<script type="importmap">
{
"imports": {
"/path/to/kv-storage-polyfill.mjs": [
"std:kv-storage", // if has native support
"/path/to/kv-storage-polyfill.mjs" // otherwise load polyfill
]
}
}
</script>
<!-- Then any module scripts with import statements use the above map -->
<script type="module">
import {storage} from '/path/to/kv-storage-polyfill.mjs';
// Use `storage` ...
</script>
结语

JavaScript 仍在不断变化。事实证明它之所以成为多年来最流行的语言是有道理的。浏览器和 Node.js 对新版 ECMAScript 版本的支持也愈加完善,甚至会提前支持一些尚未完成的提案。

  • 可查看“ECMAScript 兼容性列表: http://kangax.github.io/compat-table/

  • 支持 ECMAScript 规范的 Node.js 版本如下:ES2017:v9.11.2;ES2018:v10.3.0;ES2019:v12.0.0

在这种透明而强大的标准化流程帮助下,不断进化的 JavaScript 成为了可靠而强大的语言。

前路漫漫,我们携手共进吧!

英文原文: https://medium.com/@alberto.park/status-of-javascript-ecmascript-2019-beyond-5efca6a2d233

 活动推荐

现在的前端工程师除了普通的编码以外,还要考虑如何性能优化;如何跨端、跨平台实现功能;如何与新技术比如 AI、5G 相结合等诸多问题。

一个人学习的道路是艰辛而漫长的,而且往往效率不会特别高。如何才能快速成长,早日成为一名优秀的前端工程师?

极客时间汇集了 100+ 一线技术专家,分享包括前端、移动开发、AI 技术等相关内容,帮助前端人的自我提升,迈向全栈技术人。现申请“员工选课,企业支付”,喊老板来买单,团队一起免费学习!也可直接联系课程顾问「豆包」:13167596032

登录查看更多
0

相关内容

TC:IEEE Transactions on Computers。 Explanation:电气电子工程师学会计算机期刊。 Publisher:IEEE。 SIT:http://dblp.uni-trier.de/db/journals/tc/index.html
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【北京大学】面向5G的命名数据网络物联网研究综述
专知会员服务
36+阅读 · 2020年4月26日
Gartner:2020年十大战略性技术趋势, 47页pdf
专知会员服务
76+阅读 · 2020年3月10日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
UML建模工具一览(20190909 更新)
UMLChina
12+阅读 · 2019年9月9日
已删除
创业邦杂志
5+阅读 · 2019年3月27日
一年一版本,Sublime Text 3.2 正式发布
开源中国
4+阅读 · 2019年3月14日
34个最优秀好用的Python开源框架
专知
9+阅读 · 2019年3月1日
开发 | PyTorch重大更新,0.4.0版本支持Windows系统
AI科技评论
7+阅读 · 2018年4月25日
Advances in Online Audio-Visual Meeting Transcription
Arxiv
4+阅读 · 2019年12月10日
Deep learning for cardiac image segmentation: A review
Arxiv
21+阅读 · 2019年11月9日
Arxiv
5+阅读 · 2019年10月11日
Arxiv
6+阅读 · 2018年7月12日
VIP会员
相关VIP内容
相关资讯
UML建模工具一览(20190909 更新)
UMLChina
12+阅读 · 2019年9月9日
已删除
创业邦杂志
5+阅读 · 2019年3月27日
一年一版本,Sublime Text 3.2 正式发布
开源中国
4+阅读 · 2019年3月14日
34个最优秀好用的Python开源框架
专知
9+阅读 · 2019年3月1日
开发 | PyTorch重大更新,0.4.0版本支持Windows系统
AI科技评论
7+阅读 · 2018年4月25日
Top
微信扫码咨询专知VIP会员