这两天尝试做一套解决方案,能够只编译一套 ES2015+ 代码,在现代浏览器就正常使用,在 IE11 自动切换到 babel-standalone 实时编译。
然后偶然发现 babel@6 的一个 bug,如下:
class T {
foo() {
const {hasOn: o} = (() => {
for (let e = 0; e < 1; e++) {
if (o = 1, 2 >= o) return null;
}
var o;
})() || {};
}
}
t = new T();
t.foo();
上面这段代码其实是符合语法的。看起来,L3 使用 const
声明了变量 o
,然后在 L5 又再次试图给它赋值,似乎有修改常量之嫌。但其实,因为 L5 在另外一个块域里,而且 L7 var o;
会产生变量提升,所以这个赋值操作的是 var o
声明的局部变量。
如果你把它放在 V8 里,比如 node.js 或者 Chrome 浏览器,它就能正常执行;如果你用 babel@6 + babel-preset-es2015 转译,就会报错,说 o is read only
。
产生这个错误的原因是 babel-plugin-transform-es2015-classes 解析上面这段代码时存在错误,导致 babel-plugin-check-es2015-constants 认为常量被修改。不过我也只查到这一步,暂时不知道怎么修复这个 bug,也不知道怎么在 babel@7 里检查这个问题。有兴趣的同学可以试一下。
欢迎吐槽,共同进步