ES6 真的比ES5好很多吗?( 三 )

如果将上面的代码用Node运行,会报错:
var obj1 = _defineProperty({}, Symbol.iterator, /*#__PURE__*/regeneratorRuntime.mark(function _callee() {^ReferenceError: regeneratorRuntime is not defined因为运行库没有被引入进来,我们还得加个库,先install:
npm install --save @babel/polyfill然后把库引进来:
require("@babel/polyfill");...var f1 = function f1() {var obj1 = {[Symbol.iterator]() {return /*#__PURE__*/regeneratorRuntime.mark(function _callee() {...这增加了多少代码量,就留给读者自己去算吧 。
类虽然说class本质上跟Function的语法糖也差不多,但是,Babel转码生成出来的代码,可能比大多数同学想象的多 。
我们看一个简单的例子:
class Code {constructor(source) {this.source = source;}}code1 = new Code("test1.js");转码之后效果如下,Babel为我们生成了_createClass,_classCallCheck和_defineProperties三个函数:
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var Code = /*#__PURE__*/_createClass(function Code(source) {_classCallCheck(this, Code);this.source = source;});code1 = new Code("test1.js");依赖polyfill和runtime的内置对象我们知道,ES6新增了不少对象还有原有对象的新属性 。
比如你使用新增加的Set,Map,WeakSet,WeakMap等对象,或者是Number.isNaN这样的新方法,Babel并没有帮我们转码成ES5的语句 。
那么,这些语句在老的游览器是如何支持的呢?
答案大家可能已经猜到了,就是我们之前Generator时用到的@babel/polyfill库 。Babel polyfill库实际上是基于两个开源的库:

  1. 一个是facebook的regenerator库,目前运行时是一个700多行的文件:regenerator runtime .
  2. 另一个是core-js库,大部分的内置对象的支持都靠它 。
我们代码写成这样:
Array.from(new Set([1, 2, 3, 2, 1]));[1, [2, 3], [4, [5]]].flat(2);Promise.resolve(32).then(x => console.log(x));实际上Babel/runtime执行的是这样的:
import from from 'core-js-pure/stable/array/from';import flat from 'core-js-pure/stable/array/flat';import Set from 'core-js-pure/stable/set';import Promise from 'core-js-pure/stable/promise';from(new Set([1, 2, 3, 2, 1]));flat([1, [2, 3], [4, [5]]], 2);Promise.resolve(32).then(x => console.log(x));转码效果更好凡事皆有特例,从某些功能来讲,也许转码实现更好 。
解构赋值我们引用阮一峰老师的变量交换的的例子:
let f1 = () => {let x = 1;let y = 2;[x, y] = [y, x];};f1();转码之后变成这样:
var f1 = function f1() {var x = 1;var y = 2;var _ref = [y, x];x = _ref[0];y = _ref[1];};f1();我们先看下转码之后的字节码,有44个字节:
0xf1208293682 @0 : 0d 01LdaSmi [1]0xf1208293684 @2 : c4Star00xf1208293685 @3 : 0d 02LdaSmi [2]0xf1208293687 @5 : c3Star10xf1208293688 @6 : 79 00 00 25CreateArrayLiteral [0], [0], #370xf120829368c @10 : c0Star40xf120829368d @11 : 0cLdaZero0xf120829368e @12 : c1Star30xf120829368f @13 : 0b f9Ldar r10xf1208293691 @15 : 36 f6 f7 01StaInArrayLiteral r4, r3, [1]0xf1208293695 @19 : 0d 01LdaSmi [1]0xf1208293697 @21 : c1Star30xf1208293698 @22 : 0b faLdar r00xf120829369a @24 : 36 f6 f7 01StaInArrayLiteral r4, r3, [1]0xf120829369e @28 : 19 f6 f8Mov r4, r20xf12082936a1 @31 : 0cLdaZero0xf12082936a2 @32 : 2f f8 03LdaKeyedProperty r2, [3]0xf12082936a5 @35 : c4Star00xf12082936a6 @36 : 0d 01LdaSmi [1]0xf12082936a8 @38 : 2f f8 05LdaKeyedProperty r2, [5]0xf12082936ab @41 : c3Star10xf12082936ac @42 : 0eLdaUndefined0xf12082936ad @43 : a9Return上面更简洁的解构需要多少个字节?
答案是189字节,因为涉及到迭代器:
0xf120829376e @0 : 0d 01LdaSmi [1]0xf1208293770 @2 : c4Star00xf1208293771 @3 : 0d 02LdaSmi [2]0xf1208293773 @5 : c3Star10xf1208293774 @6 : 79 00 00 25CreateArrayLiteral [0], [0], #370xf1208293778 @10 : c1Star30xf1208293779 @11 : 0cLdaZero0xf120829377a @12 : c2Star20xf120829377b @13 : 0b f9Ldar r10xf120829377d @15 : 36 f7 f8 01StaInArrayLiteral r3, r2, [1]0xf1208293781 @19 : 0d 01LdaSmi [1]0xf1208293783 @21 : c2Star20xf1208293784 @22 : 0b faLdar r00xf1208293786 @24 : 36 f7 f8 01StaInArrayLiteral r3, r2, [1]0xf120829378a @28 : b1 f7 03 05GetIterator r3, [3], [5]0xf120829378e @32 : 19 f7 f8Mov r3, r20xf1208293791 @35 : 9f 07JumpIfJSReceiver [7] (0xf1208293798 @ 42)0xf1208293793 @37 : 65 bf 00 fa 00CallRuntime [ThrowSymbolIteratorInvalid], r0-r00xf1208293798 @42 : c0Star40xf1208293799 @43 : 2d f6 01 07LdaNamedProperty r4, [1], [7]0xf120829379d @47 : c1Star30xf120829379e @48 : 12LdaFalse0xf120829379f @49 : bfStar50xf12082937a0 @50 : 19 ff f2Mov <context>, r80xf12082937a3 @53 : 0b f5Ldar r50xf12082937a5 @55 : 96 21JumpIfToBooleanTrue [33] (0xf12082937c6 @ 88)0xf12082937a7 @57 : 11LdaTrue0xf12082937a8 @58 : bfStar50xf12082937a9 @59 : 5d f7 f6 0dCallProperty0 r3, r4, [13]0xf12082937ad @63 : bbStar90xf12082937ae @64 : 9f 07JumpIfJSReceiver [7] (0xf12082937b5 @ 71)0xf12082937b0 @66 : 65 b7 00 f1 01CallRuntime [ThrowIteratorResultNotAnObject], r9-r90xf12082937b5 @71 : 2d f1 02 0bLdaNamedProperty r9, [2], [11]0xf12082937b9 @75 : 96 0dJumpIfToBooleanTrue [13] (0xf12082937c6 @ 88)0xf12082937bb @77 : 2d f1 03 09LdaNamedProperty r9, [3], [9]0xf12082937bf @81 : bbStar90xf12082937c0 @82 : 12LdaFalse0xf12082937c1 @83 : bfStar50xf12082937c2 @84 : 0b f1Ldar r90xf12082937c4 @86 : 8a 03Jump [3] (0xf12082937c7 @ 89)0xf12082937c6 @88 : 0eLdaUndefined0xf12082937c7 @89 : c4Star00xf12082937c8 @90 : 0b f5Ldar r50xf12082937ca @92 : 96 21JumpIfToBooleanTrue [33] (0xf12082937eb @ 125)0xf12082937cc @94 : 11LdaTrue0xf12082937cd @95 : bfStar50xf12082937ce @96 : 5d f7 f6 0fCallProperty0 r3, r4, [15]0xf12082937d2 @100 : bbStar90xf12082937d3 @101 : 9f 07JumpIfJSReceiver [7] (0xf12082937da @ 108)0xf12082937d5 @103 : 65 b7 00 f1 01CallRuntime [ThrowIteratorResultNotAnObject], r9-r90xf12082937da @108 : 2d f1 02 0bLdaNamedProperty r9, [2], [11]0xf12082937de @112 : 96 0dJumpIfToBooleanTrue [13] (0xf12082937eb @ 125)0xf12082937e0 @114 : 2d f1 03 09LdaNamedProperty r9, [3], [9]0xf12082937e4 @118 : bbStar90xf12082937e5 @119 : 12LdaFalse0xf12082937e6 @120 : bfStar50xf12082937e7 @121 : 0b f1Ldar r90xf12082937e9 @123 : 8a 03Jump [3] (0xf12082937ec @ 126)0xf12082937eb @125 : 0eLdaUndefined0xf12082937ec @126 : c3Star10xf12082937ed @127 : 0d ffLdaSmi [-1]0xf12082937ef @129 : bdStar70xf12082937f0 @130 : beStar60xf12082937f1 @131 : 8a 05Jump [5] (0xf12082937f6 @ 136)0xf12082937f3 @133 : bdStar70xf12082937f4 @134 : 0cLdaZero0xf12082937f5 @135 : beStar60xf12082937f6 @136 : 10LdaTheHole0xf12082937f7 @137 : a6SetPendingMessage0xf12082937f8 @138 : bcStar80xf12082937f9 @139 : 0b f5Ldar r50xf12082937fb @141 : 96 23JumpIfToBooleanTrue [35] (0xf120829381e @ 176)0xf12082937fd @143 : 19 ff f0Mov <context>, r100xf1208293800 @146 : 2d f6 04 11LdaNamedProperty r4, [4], [17]0xf1208293804 @150 : 9e 1aJumpIfUndefinedOrNull [26] (0xf120829381e @ 176)0xf1208293806 @152 : b9Star110xf1208293807 @153 : 5d ef f6 13CallProperty0 r11, r4, [19]0xf120829380b @157 : 9f 13JumpIfJSReceiver [19] (0xf120829381e @ 176)0xf120829380d @159 : b8Star120xf120829380e @160 : 65 b7 00 ee 01CallRuntime [ThrowIteratorResultNotAnObject], r12-r120xf1208293813 @165 : 8a 0bJump [11] (0xf120829381e @ 176)0xf1208293815 @167 : baStar100xf1208293816 @168 : 0cLdaZero0xf1208293817 @169 : 1c f4TestReferenceEqual r60xf1208293819 @171 : 98 05JumpIfTrue [5] (0xf120829381e @ 176)0xf120829381b @173 : 0b f0Ldar r100xf120829381d @175 : a8ReThrow0xf120829381e @176 : 0b f2Ldar r80xf1208293820 @178 : a6SetPendingMessage0xf1208293821 @179 : 0cLdaZero0xf1208293822 @180 : 1c f4TestReferenceEqual r60xf1208293824 @182 : 99 05JumpIfFalse [5] (0xf1208293829 @ 187)0xf1208293826 @184 : 0b f3Ldar r70xf1208293828 @186 : a8ReThrow0xf1208293829 @187 : 0eLdaUndefined0xf120829382a @188 : a9Return Constant pool (size = 5)0xf1208293731: [FixedArray] in OldSpace - map: 0x0f1208002205 <Map> - length: 50: 0x0f12082936fd <ArrayBoilerplateDescription PACKED_SMI_ELEMENTS, 0x0f12082936ed <FixedArray[2]>>1: 0x0f1208004e65 <String[4]: #next>2: 0x0f1208004441 <String[4]: #done>3: 0x0f1208005619 <String[5]: #value>4: 0x0f12080051dd <String[6]: #return>


推荐阅读