2010-06-03 87 views
13

我看到這個結構是爲了得到瀏覽器的視口寬度:爲什麼Javascript的OR返回的值不是true/false?

function() { return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; } 

我理解所涉及的瀏覽器怪癖。我不明白的是爲什麼||返回值。所以我嘗試了這個alert(undefined || 0 || 3);,果然,它會警告3。我覺得這很離奇,因爲我期待truefalse。誰能解釋一下發生了什麼?

+0

是否'警報(未定義&& 0 && 3)''返回0'? – 2010-06-03 13:38:13

+2

@Rising Star:爲什麼問OP,你可以自己動手嗎?...另外,對我而言,它返回'undefined'。 – Matchu 2010-06-03 13:39:34

+3

供參考:如果你想要一個真值,做'!!(undefined || 0 || 3)' – Matt 2010-06-03 14:03:51

回答

13

在ECMAScript的標準部分11.11 Binary Logical Operators

生產LogicalORExpression請看: LogicalORExpression || LogicalANDExpression評估爲 如下:

1.評估LogicalORExpression。

2.Call GetValue(Result(1))。

3.Call ToBoolean(Result(2))。

4.如果Result(3)爲true,則返回Result(2)。

5.評估邏輯和表達式。

6.Call GetValue(Result(5))。

7.返回結果(6)。

所以評估布爾轉換每個操作數,但返回操作數的實際

如果你想知道如何使用Javascript的值轉換爲布爾值,見9.2 ToBoolean

17

JavaScript的運營商||定義爲返回左值,如果計算結果是truthy值,否則正確的價值而不是返回true本身。這就是它在規範中的定義。

我知道它有時可能很煩人,你可能會不小心結束了對你不想堅持的事情的引用,但它也允許你的例子有一個方便的技巧。一切都有其優點和缺點。

4

OR函數是一個短路或評估 - 它返回第一個不是假的元素,否則返回最後一個false元素。

其實,這是非常有用的,所以你可以寫像

a = a || someValue; 

這是一樣的

if (a==null) 
    a = someValue; 
+1

這不僅僅是「不爲空」。空字符串和數字零都被視爲「false」。 「未定義」僞值也被視爲「假」,儘管這是事情變得更加棘手的地方。編輯: – Pointy 2010-06-03 13:45:35

+0

:現在使用true和false作爲定義。查看ECMA標準,它通過toBoolean將每個值轉換爲布爾值,但在測試後返回值本身。 – mdma 2010-06-03 16:11:36

9

不要把它想成「或」表達式。它更像是一個表達式中的流量控制設備。 ||的值表達式是第一個「truthy」子表達式的值。因此,該系列的子表達式的評估停止在某些時候,彷彿

expr1 || expr2 || expr3 

(function() { 
    var rv = expr1; 
    if (rv) return rv; 
    rv = expr2; 
    if (rv) return rv; 
    return expr3; 
})() 
1

某些值,例如零,""undefined,被視爲假。其他的都是真的,所以||運算符只是返回它給出的對中的第一個非零(即真)值。這對於像上面的代碼這樣的技巧很有用,但我猜測它並沒有添加到語言中,只是爲了讓您跳過奇怪的if語句。因爲更高級別的語言(比如BASIC ...是的,也許是更高級別的一個奇怪的定義)使用固定的常量來表示true和false--通常是0和-1,或0和1.

+2

注意「任何非零」的定義。 'false','undefined'和'「」'都不爲零,但不認爲是真的。 – Matchu 2010-06-03 13:43:26

+0

@Matchu謝謝,這是我的perl背景顯示。 :(固定的 – 2010-06-03 14:08:39

+0

我喜歡把||和&&的行爲看作「確定真實性或虛假性的論證的價值」。 – 2013-08-17 20:33:55

2

這只是它的設計方式。 ||,就像&&是一個短路操作符,按順序評估表達式,在表達式滿足條件併產生表達式結果後停止。同樣是真實的&&

var myObj = { "Test": { "Foo":"Bar" } }; 
var myObj2 = { "Foo": "Bar" }; 

alert(myObj.Test && myObj.Test.Foo); // will alert "Bar"; 
alert(myObj2.Test && myObj2.Test.Foo); // will alert undefined; 
相關問題