簡體   English   中英

JS函數在if語句中的奇怪行為,為什么?

[英]weird behavior of JS functions in an if statement, WHY?

為什么下面的代碼會返回“明顯的”“驚喜!” (最后“怎么回事?” )。 它應該返回“預期” ,不是嗎?
在第一個if我們使用匿名函數,在第二個我們使用'命名'函數。

var a = 5;
if (a == 5) {
    var b = function () {
        return "obvious";
    };
} else {
    var b = function () {
        return "never";
    };
}

if (a == 5) {
    function c() {
        return "expected";
    }
} else {
    function c() {
        return "surprise!";
    }
    function d() {
        return "how come?";
    }
}

alert(b());
alert(c());
alert(d());

所以這意味着, function a(){} is NOT equal to var a = function (){}

那么,第二個問題,為什么JS需要這種奇特的行為呢? 這有什么好處?

不,它不應該,因為函數定義語句的語義不是你顯然認為它們的語義。

函數定義語句始終被提升到封閉函數(或范圍)的頂部。 如果有多個具有相同名稱的函數定義語句,則最后一個獲勝。 這不是一個動態的執行時間。 將函數定義語句置於條件代碼塊中應該在語法上被禁止,但它不是。 只是不要這樣做。

您當然可以使用函數實例化表達式來創建分配給變量的函數對象。 那會像你期望的那樣工作。

所有變量聲明和函數聲明都被提升到作用域的頂部,在本例中是腳本的頂部。 這意味着代碼被解釋為是,

var a,b;
function c() { 
    return "expected"; 
} 
function c() { 
    return "surprise!"; 
} 
function d() { 
    return "how come?"; 
} 

a = 5; 
if (a == 5) { 
    b = function () { 
        return "obvious"; 
    }; 
} else { 
    b = function () { 
        return "never"; 
    }; 
} 

if (a == 5) { 
} 
else { 
} 

alert(b()); 
alert(c()); 
alert(d()); 

請注意,最后一個if語句為空,因為它們包含的所有函數聲明都被提升。 函數c的第二個聲明掩蓋了第一個。

我建議你避免在塊語句中使用funciton聲明語法。 它是技術上不合法的JavaScript,但每個瀏覽器都支持它,即使它引起了你所注意到的混亂。

function a(){}不等於var a = function(){}。

正確。 從來沒有這種情況。

那么,第二個問題,為什么JS需要這種奇特的行為呢? 這有什么好處?

JavaScript提升函數聲明,以允許稍后在腳本中聲明的函數由腳本中較早的函數使用。 這使代碼組織更加靈活。

@Pointy是對的。 在計算第一個if語句之前,正在聲明函數c()和d()。 這就是為什么當你打電話給警報時,他們會做他們做的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM