作者:Yann s翻译:疯狂的技术宅
原文:https://medium.com/engineered...
未经允许严禁转载
什么是 JavaScript?据 Wikipedia 的描述,它是一种符合 ECMAScript 规范的脚本语言。 ES6,ES7等这些名字你可能听说过,你也很可能已经使用 ES6 有一段时间了(在很多情况下通过 Babel 使用)。
我确定你们中的大多数人都在使用许多不同的 ES6 新功能,而无需问自己:这真的是 ES6吗,浏览器支持该功能吗?不过你对 Babel 在 2019 年进行的转换了解多少?你是否重新了解了 ES 中的内容?自从首次提出 ES6 提案以来,删除了哪些内容?自最初的 ES7 提案以来又增加了什么?
让我们坐下来回顾一下 ES 的当前状态。自 Babel 和 ES6 诞生以来都发生了什么,什么已完全集成?
一些历史和扫盲
我认为让你重新了解某项目的不同阶段是很有用的。
本质上,这些功能经历了从 0 到 4 的阶段,0 是最早的阶段,而 4 是“准备发布”。
阶段 0 是纯属有人提出的想法,将其整理为阶段 1 的提案,进行审查和讨论,直到阶段 3 为止,最终将其划分为阶段 4 的优先级。到达阶段 4 后,将会在浏览器中实现并计划发布。
在此处获取所有 deets:https://tc39.es/process-docum...
ES6 和 ES7 —— 提醒
简而言之,ES6(或 ES2015)是根据 2015里程碑 通过了第4阶段的一系列功能。换句话说,如果你对 ES6 有很好的理解,并且对 ES7 有一定的了解,那么你大约有4年的时间可以追赶……没有压力。
让我们看一下 ES6 的正式组成部分。顺便说一下,所有这些功能在所有浏览器中都得到正式支持。换句话说,不管你使用哪个浏览器都不需要 Babel(除非你需要支持 IE 11)。
在 ES6 中,我们能够得到:
创建和继承类的能力。
class MyComponent extends React.Components {}
具有导入和导出功能的ES6模块。
import * from 'React';export default MyComponent;
生成器
let fibonacci = {
*[Symbol.iterator]() {
let pre = 0, cur = 1
for (;;) {
[ pre, cur ] = [ cur, pre + cur ]
yield cur
}
}
}
我们还有:模板,箭头函数,Promise,新的数字类型,Const/Let,类型化数组,数组解构,Map/Set,符号。
这里是所有功能的列表:http://es6-features.org
你注意到了吗?装饰器,对象解构(例如 React props:{…props}
)等都不属于 ES6!
关于在 ES7(ES2016) 中,以下是我们能够得到的。这是一个很小的更新:
-
幂运算符
base ** exponent
- 数组包含
array.includes(myItem) // true 或 false
资料来源: http://ecma-international.org...
你可能已经注意到 Async/Await 不是 ES7 的一部分,而是属于 ES8!
ES8, ES9, ES10
在过去的两年中,每个接受过 JavaScript 相关面试的人都被问到过 ES6 是什么以及它带来什么功能。但是有人发现 JS 显然并没有突然停留在 ES6 和 ES7 上,但是没有人问你个吗?这是你纠正问题的机会!
在 ES8(ES2017)中,以下是可用功能:
- Object.entries / Object.values(数组的值/键等效对象)
- 字符串填充
myString.padStart(2); // 或 padEnd
- Trailing coma
function test(a,b,c, ) // notice the coma after c
- 原子和共享内存:https://developer.mozilla.org...
当然还有 Async/Await 函数:
async MyAjaxGetCall(url) {
return ajax.get(url)
}const response = await MyAjaxGetCall("/getUsers");
console.log(response) // response is available without using promise.then
如果你已经阅读了这篇文章,那么现在应该明白了:除少数例外,这些功能是 Stage 4,你可以在没有 Babel 的浏览器中使用它们(也就是说,ES8 是 ES2017,它仍然是最新的, Edge 和 Opera 之类的引擎对某些实现滞后了一点)。
现在转到 ES9。就像 ES8 和 ES6 一样,ES9(或ES2018)是一个相当重要的更新:
- 解除模板字面量限制(https://tc39.es/proposal-temp...)。现在,允许在模板中使用复杂的语法(例如:LaTex)
- 异步迭代器:可以将迭代器用于异步操作,例如读取 HTTP 流(https://tc39.es/proposal-asyn...)以及引入 for-wait-of
- Promise.finally:https://github.com/tc39/propo...
-
对象销毁。是的,在这里,你已经用了很多年了,它是一项 ES9功能。来自非 react 开发人员的提醒:它允许你:
myNewObject = {a,b,c, …object}
- 还包括 unicode 转义和对正则表达式的改进(https://github.com/tc39/propo... ,https://github.com/tc39/propo...)和 https://github.com/tc39/propo...)。
大多数浏览器已经支持这些功能!
最后,转到 ES10(或 ES2019)!
- Array.flat:
[[1,2],3]).flat() // [1,2,3]
- Array.flatMap: 等同于
map().flat()
- Object.fromEntries:
Object.entries
的反向操作(参见此处) - String.trimStart() 和 String.trimEnd(): 删除字符串中的多余空格
- 可选的 Catch 绑定:无需在 catch 中添加参数(现在你可以用
} catch {
而不是} catch(e){
) - 重新提出
Function.toString
的行为一致性的问题🥳🥳🥳 - 符号说明
- BigInt(64位数字)
- 改进了对 JSON.stringify() 的 Unicode 支持
- 如果 key 相同,则 Array.sort 保留其顺序
const array = [
{key: 2, value: 'd'},
{key: 1, value: 'a'},
{key: 1, value: 'b'},
{key: 1, value: 'c'},
];
array.sort(...)
/*
[
{key: 1, value: 'a'},
{key: 1, value: 'b'},
{key: 1, value: 'c'},
{key: 2, value: 'd'},
]
*/
- 将 JavaScript 设为 JSON 的超集(此处有详细信息)
那么 ES5 呢?
如果 ES6 是 ES2015,而 ES7 是 ES2016,你能猜出 ES5 属于哪一年吗?
…你输了! (除非你真的知道,但因为我听不到你的声音,所以我假设你错了)。 ES5 是 ES2009!
在 ES5 之前,最后一次 ES 更新是在 1999 年!
如你所见,从 97 到 99 更新非常频繁,在之后的 16 年里,ES5 是唯一的更新!
我们如何解释呢?好吧,我认为这有两个因素。
第一个是技术上的:“JavaScript 很烂”。老实说,确实如此。那时,我们有一些 JS 的替代品:Java Applets,ActiveX 甚至 Flash。
直到 2011 年之前,不仅这些技术比 JS 快好几个数量级, 而且它们还具有我们仍在为 JS 努力争取的很多功能。 (Java 具有所有的语言功能,例如类和装饰器,支持多线程,OpenGL,套接字等)。当 Chrome 和 Google 入场后并在 2013 年宣布淘汰 Java(然后是 Flash)时,JS 赶上其竞争对手的征战已经开始。两年后,我们有了ES6。
第二个因素是经济上的:2000 年是互联网泡沫爆发的一年。对于你们中最小的孩子,想像一下几年前的比特币,互联网初创公司在 90 年代后期是一样的。初创公司为了获得大量的风险投资在名称的末尾添加了 .com(就像现在的 mySuperStartup.ai 一样),直到其价值在 20 年代突然下降。这是一个非常基本的解释,请你看一下 wikipedia 上文章来获得更详细的解释。
关键是,Internet 不再获得使 JS 和与 Web 相关的技术成为焦点所需的吸引力。后来随着 Amazon、Facebook 和 Google 的兴起,Web 有了新的发展理由,我们选择 JS 是合乎逻辑的! Chrome 于2008 年发布,并在 2014 年成为最受欢迎的浏览器:这是 ES6 发行的第一年。
少了些什么东西? (被拒绝的提案)
这是一份从未进入第 4 阶段提案的详尽列表。你可以在此处阅读更多信息:https://github.com/tc39/propo...
Object.observe
最初它允许 JS 观察代码中的值:
var obj = {
foo: 0,
bar: 1
};
Object.observe(obj, function(changes) {
console.log(changes);
});obj.baz = 2;
// [{name: 'baz', object: <obj>, type: 'add'}]
这是一个很棒的功能,很明显你可以通过代码(或 polyfill)来实现它,但是在浏览器中实现它的前提是实现更快的响应保证(例如:Angular 使用了大量观察者)。之所以撤销,是因为他们无法实现稳定性能。 此处有更多详细信息。
可取消的 Promise
不言而喻,我敢肯定,这并不是唯一缺少的功能。这个想法允许开发人员随时取消任何 Promise 的执行。
用例会有所不同,例如,在异步操作时使客户端超时,或者,如果你有一个选项卡驱动的导航系统,并且用户在加载当前选项卡的内容之前单击了另一个选项卡。
blöcks
我之所以仅提及这一点,是因为我喜欢它的名字,也因为它是一个与 Go Routines 或 C# Tasks 类似的出色功能。
const blöck = await {|
// This code is Async, but most importantly, executed in another thread
|};
其他
还有一些有趣的建议,例如可调用的构造函数。其中大多数要么由于原始作者的原因而被撤回,要么因为与现有计划中的特征冲突或重叠而被拒绝。
下一步是什么?
目前,阶段 0 ~ 3 中有一些令人兴奋的东西。我会强调一些:
Observables (Stage 0)
Observe 已被拒绝,但战斗并没有停止,Observable 是一项改进 API 的提案,旨在消除 Observe() 遇到的性能瓶颈。
https://tc39.es/proposal-obse...
String.ReplaceAll (Stage 3)
https://github.com/tc39/propo...
顶级 Await (Stage 3)
使用 Await 要求你处于异步函数内,这意味着你不能简单地删除包含 await 的脚本标签,这不一定有意义,并且限制了 ES6 模块在浏览器中无缝运行。它还允许你执行 fetch 操作或者不执行操作。
// You can do this in a .js file:
fetch(...).then((res) => something = res);
// But you can't do this unless you have a Async keyword
const res = await fetch(...);
https://github.com/tc39/propo...
可选链
也称为猫王(Elvis)运算符(我就是要这样称呼它,你无法阻止我!),可让你轻松浏览对象而不会引发错误:
const test = myObject && myObject.a;
// equivalent to
const test = myObject?.a;
之所以称为猫王(Elvis)运算符,是因为运算符 ?: 看起来像猫王的侧脸。
该提案还提到了 Nullish 合并运算符:
let x = 0 || 1; // x is 1 because 0 is falsy
let x = 0 ?? 1; // Since 0 is defined, x is 0
结论和常见问题
好长!可以肯定的是,你记不住所有内容,坦白地说,我也记不住!希望本文对你有一个全面的概述,并鼓励你重新考虑对 JavaScript 的看法!我想从最常见的问题开始解答:
我仍然需要 Babel 吗?
很好的问题!考虑到 JS(ES6 至 ES9)的最常见功能,已经完全在除了 IE11 之外的浏览器中实现。你可能会认为:“那么,这还不够好”。是的,还不够好,因为你做出了选择,所以你应该考虑:
- 在我撰写本文时,目前 IE11 的浏览器占有率为 1.86%。但是不支持 IE11 并不意味着你会失去 1.86% 的受众群体,因为你应该考虑到人们能够切换浏览器,而且你的目标受众群体实际使用 IE11 的比例可能要低得多人员(例如:如果你定位的是年轻人)或技术爱好者)。
- 与不支持 IE11 所失去的金钱相比,支持 IE11 是否会给你带来更多的收入?为 IE11 开发不只是使用 Babel。你还需要在该浏览器上测试所有功能,因为即使用了 Babel,其中一些功能也会受到损坏,然后找到所有这些问题的修复程序。间接费用可能不值得。
同样,使用原声函数比 Babel 的已编译代码的速度最多可提高3倍,正如这个基准测试所强调的那样:https://www.inovex.de/blog/no...。 Babel 还会增加包的大小,最后,在开发时会增加构建时间。所以为什么要在每个项目中都使用 Babel 呢!
与使用原生函数相比,Babel 降低了代码执行速度,增加了包大小,并增加了构建时间。你真的在每个项目中都需要它吗?
为什么要添加诸如 let 之类的新关键字而不是进行更新?
你可能想知道为什么 JS 引入 let 而不是改进现有的 var关键字。答案很简单:这样做是为了保持向后兼容性。你不想破坏 web,对吧? (我是认真的!)
那么 Typescript 呢?
Typescript 的规则是第 3 阶段的提案。
在哪里可以找到更多信息?
Github 和官方网站在这里:
https://github.com/tc39/propo...
https://tc39.es/?source=post_...
本文首发微信公众号:前端先锋
欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章
欢迎继续阅读本专栏其它高赞文章:
- 深入理解Shadow DOM v1
- 一步步教你用 WebVR 实现虚拟现实游戏
- 13个帮你提高开发效率的现代CSS框架
- 快速上手BootstrapVue
- JavaScript引擎是如何工作的?从调用栈到Promise你需要知道的一切
- WebSocket实战:在 Node 和 React 之间进行实时通信
- 关于 Git 的 20 个面试题
- 深入解析 Node.js 的 console.log
- Node.js 究竟是什么?
- 30分钟用Node.js构建一个API服务器
- Javascript的对象拷贝
- 程序员30岁前月薪达不到30K,该何去何从
- 14个最好的 JavaScript 数据可视化库
- 8 个给前端的顶级 VS Code 扩展插件
- Node.js 多线程完全指南
- 把HTML转成PDF的4个方案及实现
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。