函數(shù)作用域提升以及函數(shù)表達(dá)式指定命名

// 思考下面代碼運(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è)問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容