730 words
4 minutes
Babel 编译的 loose 模式简述
Contents
前言
我们都知道,babel
可以将 es6
的代码转换为 es5
的代码。其中presets
有两种模式可以选择。
- 将代码转换为最接近
es6
规范的正常模式loose: false
,他能保证转换前后的语义是 99% 一致的 - 将代码转换为更简单的
es5
模式loose: true
我们项目用的是 loose: true
我们举一个具体的例子
ES6 原生模式
下面 es6
的 class
语法
运行结果为控制台输出
x,y
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
}
const point = new Point(1,2);
//es6规范规定,class上面的方法是不可枚举的
for( let i in point ) { console.log(i) } //x,y
宽松模式
如果宽松模式 loose:true
模式转换的代码
运行结果为控制台输出
x,y,toString
var Point = /*#__PURE__*/function () {
"use strict";
function Point(x, y) {
this.x = x;
this.y = y;
}
var _proto = Point.prototype;
_proto.toString = function toString() {
return "(" + this.x + ", " + this.y + ")";
};
return Point;
}();
var point = new Point(1, 2);
for (var i in point) {
console.log(i);
}
严格模式
如果是严格模式 loose:false
运行结果为控制台输出
x,y
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
require("core-js/modules/es.symbol.js");
require("core-js/modules/es.symbol.description.js");
require("core-js/modules/es.symbol.iterator.js");
require("core-js/modules/es.symbol.to-primitive.js");
require("core-js/modules/es.error.cause.js");
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.date.to-primitive.js");
require("core-js/modules/es.number.constructor.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var Point = /*#__PURE__*/function () {
"use strict";
function Point(x, y) {
_classCallCheck(this, Point);
this.x = x;
this.y = y;
}
return _createClass(Point, [{
key: "toString",
value: function toString() {
return "(".concat(this.x, ", ").concat(this.y, ")");
}
}]);
}();
var point = new Point(1, 2);
for (var i in point) {
console.log(i);
}
我们可以观察到,宽松模式产生了比较简单的 es5
代码,但是和规范定义有些差别。正常模式则会将这些方法定义翻译为 Object.defineProperty
,并设置成不可枚举,和直接运行 es6
代码得到相同的结果。
总结
loose
模式可以产生更简单的代码,类似手写es6
,运行效率更高。如果后续使用es6
原生模式运行项目,可能会有意想不到的bug- 正常模式使用复杂的
es5
代码去模拟es6
的规范,运行效率稍稍下降,但如果后续使用es6
原生模式运行项目,行为基本上是一致的。
Babel 编译的 loose 模式简述
https://dabuside.github.io/posts/babel_loose_mode/