// 思考下面代碼運(yùn)行結(jié)果
print(); // 輸出print
function print () {
console.log('print');
}
...
print(); // 無輸出
var print = function () {
console.log('print');
}
...
print(); // 報(bào)錯(cuò)print is not defined
let print = function () {
console.log('print');
}
第一段代碼可以運(yùn)行并打印出結(jié)果是因?yàn)閖s解析時(shí)會把函數(shù)提升解析,所以雖然我們是在函數(shù)定義之前發(fā)生的調(diào)用,但一樣可以調(diào)用成功
第二段無輸出,是因?yàn)榘春瘮?shù)表達(dá)式聲明,一樣存在提升的問題,但這時(shí)瀏覽器提升的變量,所以這時(shí)會先定義print為undefined
第三段原因是因?yàn)槲覀兪褂昧薼et,let不存在變量提升,所以調(diào)用報(bào)錯(cuò)
一般情況下我們都是使用let去定義各種變量,但是為了兼容性,我們會使用babel對代碼進(jìn)行轉(zhuǎn)碼,轉(zhuǎn)碼后神奇的事情就出現(xiàn)了
'use strict';
print();
var print = function print() {
console.log('print');
};
這時(shí)的代碼就會變成和第二段代碼一樣,可以運(yùn)行了,這個(gè)例子不是很正常的例子,因?yàn)殄e(cuò)誤明顯,但在瀏覽器完全支持es6之前,我們還是要注意考慮變量提升的問題,雖然你用了let,但編譯器還是會把它轉(zhuǎn)為var,另外再思考下,為什么babel在對一個(gè)匿名函數(shù)表達(dá)式進(jìn)行轉(zhuǎn)換時(shí),會加一個(gè)函數(shù)名呢?
// 匿名函數(shù)表達(dá)式
var add = function (a, b) {
return a + b;
}
...
// 指定函數(shù)名的表達(dá)式
var add = function my_add (a, b) {
return a + b;
}
我感覺這個(gè)地方是主要是為了方便調(diào)試,比如我們在控制臺輸入add
// 匿名函數(shù)表達(dá)式的控制臺輸出
? (a, b) {
return a + b;
}
...
// 指定函數(shù)名的表達(dá)式
? my_add(a, b) {
return a + b;
}
在現(xiàn)在這個(gè)簡單函數(shù)我們當(dāng)然可以一眼就看明白這些函數(shù)干什么的,但是如果函數(shù)很復(fù)雜呢,你還能直接明白這個(gè)函數(shù)是做什么?所以給函數(shù)加上一個(gè)描述的名詞會方便你的調(diào)試,我猜測這也是為啥babel進(jìn)行轉(zhuǎn)換時(shí)會加上函數(shù)名的原因,這點(diǎn)在github上的一個(gè)討論也驗(yàn)證了這個(gè)問題