在使用 babel 轉(zhuǎn)換 ES next 代碼的時候,并不會將 Symbol 直接轉(zhuǎn)換成 ES5 中對應的內(nèi)容穆律,需要引入額外的 polyfill 才能正常工作。
有的團隊為了避免引入這個額外的 polyfill 导俘,會選擇不使用 Symbol 峦耘,包括通過 babel 生成 Symbol 的特性(比如 for of
等)。
這時候就會有個比較隱蔽的地方需要注意旅薄,就是盡量不要讓 babel 生成這樣的代碼:
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
這個里面包含了一個 Symbol
辅髓,為了讓 Symbol
不至于報錯,又要想辦法在全局先聲明一下 Symbol
變量少梁,比較丑陋利朵。
目前在實踐中,發(fā)現(xiàn)這樣的 ES next 代碼會生成上述代碼:
function fn1() {
if (1) {
let a = 1;
filter(function fn() {
console.log(a);
});
return;
}
}
生成的代碼為:
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function fn1() {
if (1) {
var _ret = function () {
var a = 1;
filter(function fn() {
console.log(a);
});
return {
v: void 0
};
}();
if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v;
}
}
這段代碼有什么特征呢猎莲?就是在 if
塊中定義了函數(shù)绍弟,函數(shù)中訪問了 if
塊中的“塊級變量”,并且 if
塊使用了 return
語句著洼。
可以看出樟遣,babel 為了保證 if
塊內(nèi)變量的作用域,會套一個匿名函數(shù)身笤,同時由于 if
塊中存在 return
返回豹悬,所以就用 _ret
來接收匿名函數(shù)的返回值。然后后面為啥會生成那串長長的對 _ret
的類型判斷代碼液荸,目前還不太清楚瞻佛,可能要結(jié)合 babel 的內(nèi)部處理邏輯去看了,單從生成的代碼看娇钱,這個完全是多余的伤柄。
推而廣之, for
塊等局部非函數(shù)作用域都會有類似的問題文搂。
實際上适刀,從代碼編寫規(guī)范角度來看,是不應該在這種局部作用域塊里面定義函數(shù)的煤蹭。函數(shù)應該是一段通用的代碼笔喉,不應該縮在那一小塊里面取视。