文章插图
不吹不捧,5和6做个对比,ES6及以上版本是由多个功能组成的,这是一个多维度的比较,不能简单抽象成6比5好 。
为了兼容老的浏览器,尤其是IE系列,使用ES6以上规范的前端代码往往使用Babel等转码工具转码成ES5的代码 。
距离发布ES6的2015年已经过去了7年了,现在浏览器对于ES6的兼容性如何呢?
我们来看下CanIUse的数据:
文章插图
可以看到,有98.14%的浏览器支持ES6. 没有超过99%的原因是因为2015年发布的Opera Mini还有1.08%的使用率 。
针对手机端,2016年以后发布的Safari on IOS和Chrome等全部都支持ES6.
Safari on iOS 7-9.3目前的用户占比0.15%.
Android从5版本开始WebView已经全线支持ES6.
从数据上看起来,因为数量很少的老设备导致近99%以上的设备能力没有应用起来,似乎并没有说服力 。
另外,很多应用针对低端机有特殊的处理,中高端机一定是近期的老设备 。至少针对中高端机,转码的兼容性必要性基本上是可以忽略的 。
不过,ES6及以上版本是由多个功能组成的,不能简单抽象成6比5好 。
我们将主要的功能转码和不转码做一个对比 。
不转码效果更好constconst是要带常量检查的 。我们来个例子:
let f1 = () => {const a = 0;a = 2;};f1();
转码之后,Babel帮我们生成了一个_readOnlyError函数 。function _readOnlyError(name) { throw new TypeError(""" + name + "" is read-only"); }var f1 = function f1() {var a = 0;2, _readOnlyError("a");};f1();
这个不用看字节码了,看源码就知道是哪个更好了 。数组拷贝ES6之后,我们做数组拷贝使用扩展运算符"...".
const a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let a2 = [...a1];
Babel做的转码也不含糊,一个concat函数搞定:var a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];var a2 = [].concat(a1);
但是,从字节码角度来看,就不一样了 。因为v8提供了CreateArrayFromIterable指令 。所以,转码之前,9个字节的指令就搞定了:
Bytecode length: 9Parameter count 1Register count 2Frame size 16OSR nesting level: 0Bytecode Age: 00x3c140829374e @0 : 79 00 00 25CreateArrayLiteral [0], [0], #370x3c1408293752 @4 : c4Star00x3c1408293753 @5 : 7aCreateArrayFromIterable0x3c1408293754 @6 : c3Star10x3c1408293755 @7 : 0eLdaUndefined0x3c1408293756 @8 : a9Return Constant pool (size = 1)0x3c1408293721: [FixedArray] in OldSpace - map: 0x3c1408002205 <Map> - length: 10: 0x3c1408293715 <ArrayBoilerplateDescription PACKED_SMI_ELEMENTS, 0x3c14082936e5 <FixedArray[10]>>
转码之后就是函数调用了,还有生成一个空数组,一共需要21个字节:0x3c1408293696 @0 : 79 00 00 25CreateArrayLiteral [0], [0], #370x3c140829369a @4 : c4Star00x3c140829369b @5 : 7b 01CreateEmptyArrayLiteral [1]0x3c140829369d @7 : c1Star30x3c140829369e @8 : 2d f7 01 02LdaNamedProperty r3, [1], [2]0x3c14082936a2 @12 : c2Star20x3c14082936a3 @13 : 5e f8 f7 fa 04CallProperty1 r2, r3, r0, [4]0x3c14082936a8 @18 : c3Star10x3c14082936a9 @19 : 0eLdaUndefined0x3c14082936aa @20 : a9Return Constant pool (size = 2)0x3c1408293665: [FixedArray] in OldSpace - map: 0x3c1408002205 <Map> - length: 20: 0x3c1408293659 <ArrayBoilerplateDescription PACKED_SMI_ELEMENTS, 0x3c1408293629 <FixedArray[10]>>1: 0x3c1408202e9d <String[6]: #concat>
String.raw对于String.raw,转码也是会多生成函数的 。比如转码前是这样:
let f1 = () => {String.raw`n`;};f1();
转码之后,Babel帮我们生成了一个_taggedTemplateLiteral函数:var _templateObject;function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }var f1 = function f1() {String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["n"])));};f1();
SymbolSymbol是ES6新增的数据类型 。在ES6里,我们要判断其类型,直接使用typeof运算符就好 。
let f2 = () => {let s1 = Symbol();return typeof s1;};
这可难为Babel了,都得引入一个库才能解决:function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }var f1 = function f1() {var s1 = Symbol();return _typeof(s1);};
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 莎士比亚的四大喜剧分别是什么内容? 莎士比亚四大喜剧
- 团购怎么做 聚团购
- 海外代购平台有哪些比较靠谱 黑五海淘
- 陈小春|被误认为是港星的10位内地明星,一个比一个有故事,有人已去世
- 简历里的求职意向怎么写比较合适? 求职意向怎么写
- 白夜追凶|比《白夜追凶》还精彩的6部探案剧,你不一定全看过?
- 先锋股份2021年净利6070.3万同比减少17.85% 公允价值变动损益同比减少
- 伊能静|伊能静儿子穿女装,裸上身妩媚妖娆,眼神勾人比妈妈还有女人味
- 最近火了的“一元脸”,真的是小脸的标准吗?
- 比黄金、白银走势更牛!钯金持续刷新历史高点,这只正牌概念股却没怎么涨!分析称:还得涨