![](/img/trans.png)
[英]Why do both “[] == true” and “![] == true” evaluate to false?
[英]Why does `false && true || true` evaluate to true?
false &&任何短路評估為假。
鑒於此信息,我希望false && true || true
false && true || true
評估為false則為true。 然而,這種情況並非如此。 只有當語句寫成如下時,才會給出預期結果( false
):
false && (true || true)
一位同事和我試圖解決這個問題,我們可以提出的最接近的事情就是按照優先順序評估該聲明。 根據MDN運算符優先級 logical-and
在logical-or
具有更高的預測logical-or
建議將條件評估為false && true
是單個語句,然后繼續確定false || true
的布爾條件 false || true
是那么true
。 寫出來,這將是:
(false && true) || true
這里不對勁。 它是文檔,JavaScript解析邏輯或我的解釋。
我添加了賞金,因為沒有給出的答案真正理解這個問題。 如上所述: MDN邏輯運算符頁面准確說明:“false &&任何短路評估為false。”
你正在看優先級錯誤。
&&首先完成,然后是|| 所以你看起來是怎么寫的:
(false && true) || true
所以MDN鏈接是正確的。
該語言通過將表達式解析為抽象語法樹來工作。 你的表達式為false && true || true
false && true || true
被解析為:
||
/ \
&& true
/ \
false true
只有在建立AST之后,才能進行短路評估。 該
false &&任何短路評估為假。
quote僅適用於有效的子樹,其中false
和anything
都是&&
node的子樹,如下所示:
&&
/ \
false true
這意味着只有false && true
才能將short-ciruit評估為false
並導致false || true
false || true
被評估為true
你的困惑都歸結為對優先權的誤解。
數學模擬將是“零乘以任何等於零”。 請考慮以下表達式:
0 x 100 + 5
在任何編程語言或一個體面的計算器中,這個評估為5.“零時任何事物”公理是正確的 - 但在這種情況下,“任何東西”都是100
,而不是100 + 5
! 要了解原因,請將其與此進行比較:
5 + 0 x 100
無論是在開頭還是結尾添加5都無關緊要 - 運算符優先級規則從語句中刪除歧義。
在JavaScript布爾邏輯中, &&
優先級高於||
。 由於每個操作員都是可交換的 ,所以寫作
false && true || true
和寫作完全一樣
true || false && true
JavaScript將以這種方式解析此表達式:
1) false && true //evaluates to false
2) false || true //equals true. The first false is the result above
很容易跟蹤JavaScript如何以這種方式解析整個表達式:
(function(){alert(1); return false; })() &&
(function(){alert(2); return true; })() ||
(function(){alert(3); return true; })()
我們這樣說吧。 寫這篇MDN文章的人說得非常糟糕/做了一個小錯誤
正如你所指出的那樣:
false &&任何短路評估為假。
任何理性的人都會認為任何事物都是任何復雜性的邏輯表達。 但是,這將是錯誤的閱讀(與布爾邏輯規則相矛盾)。
false && true || true == true
另外兩位回答者已經解釋了為什么會這樣。 它只是邏輯運算符&&和||的順序。 首先處理&&,下一步|| 被處理
現在,回到糟糕的措辭。 他們應該說的是以下內容。 請注意我添加的附加括號。
false && (anything) is short-circuit evaluated to false.
我在這里使用括號作為一種方式來表明邏輯表達式的其余部分應該獨立於“假”部分進行評估。 如果它是獨立評估的,那么短路它可以正常工作,因為false && == false。
但是,只要我們有一些無法獨立評估的表達式,那么原始措辭就不起作用。
例如false && true || true
由於順序或邏輯運算,無法獨立評估false && true || true
。 但是false && doSomething()
可以。
首先考慮這個基本算術表達式:
A * B + C
乘法優先,因此結果如下
(A * B) + C
同樣, &&
優先,所以
A && B || C
是相同的:
(A && B) || C
就短路而言,如果A
為false
,可以縮短的Anything
都是B
所以,如果你有類似的東西:
(false && takesALongTimeToDetermine()) || true
它會跳過評估takesALongTimeToDetermine()
我應該注意到這一點: 短路永遠不會改變答案 。 這是一個優化。 由於&&
只能評估到true
,如果兩個操作數都是true
,它不會打擾檢查第二個操作數是什么,如果第一個是false
,因為它已經知道答案是false
。 使用||
進行相互優化 :如果第一個操作數為true
,則返回true
而不考慮第二個操作數的值。 存在這種優化,以便您的代碼運行得更快 - 它永遠不會改變答案 。 它在MDN中提到的唯一原因是因為如果你的&&有一個操作數需要比另一個更長的計算時間,那么你需要將它列為第二個。 (這也很重要因為如果takesALongTimeToDetermine()
除了返回一個值之外還做了一些事情,IE,如果它打印出你期望的日志語句,如果函數被短路,你將看不到它。但是這仍然沒有與&&
返回的答案有關。)
你是對的, MDN邏輯運算符上的措辭有點含糊不清。
你不應該把任何 東西想象成&&
之后的任何東西 ,而是任何右手邊的算子到&&
。
&&
需要2個表達式:一個位於&&
的左側,另一個位於右側。
在您的示例中: false && true || true
false && true || true
,false是左表達式,第一個true是右表達式。 以下|| true
|| true
不是&&
運算符將評估的內容的一部分。
短路意味着不會浪費評估正確表達式的循環,如果它不再影響邏輯運算符的結果。
在這個例子中,這意味着將忽略false && true
的右側表達式( true
)(因為|| true
不是該表達式的一部分)
所以在執行中,這將是會發生的事情:
&&
&&
兩邊,需要進行評估 false
)的計算結果為false true
)是短路的,因為無論結果如何,邏輯運算符都不會產生任何false
false && true
已被評估為false
||
將被評估下一個( false && true
的結果為false
,因此使得false || true
) false
)的計算結果為false true
)的計算結果為true false || true
false || true
已被評估為true。 true
您可能缺少的是操作員只考慮操作員每一側的單個參數。
所以來自: false && true || true
false && true || true
與false
相比,只考慮第一個true
。
所以這個評估為false || true
false || true
,最后評估為true
MDN文章的“任何內容”部分可能會在您的案例中有點誤導。
這個求值為true的原因是因為OR的優先級高於AND,所以它的等價語句是:
(false && true) || true
這是一個false || true
的重復false || true
false || true
將始終評估為true。
False boolean = 0;
True boolean = 1;
“&&”運算符=乘法運算;
“||” =加;
好? 所以,如果你這樣:
if(true && false || true)
等於這個:
((1 x 0) + 1)
您的解釋是不正確的,並且您是正確的,運算符優先級是它評估為true的原因。 您缺少的是抽象語法樹上下文中anything
的含義。
由於操作的順序,你最終會得到一棵樹
||
/ \
&& true
/ \
false anything
anything
的范圍,不包括樹的右側的真實。
你可以在這里看到來自俄亥俄州立大學的一些注釋 。 它們適用於所有語言。
“false && anything”中的“false”和“nothing”絕對是指Javascript表達式/值(如@ Erbureth的答案中所示),而不是源代碼。 以下是證明此聲明的示例:
“短路”的Javascript代碼(每行一個)
var a=false; a && 3
!1 && alert("Never!")
(1==2) && "x"
不“短路”的Javascript代碼(每行一個)
<script>false && </script><p>Other page content...</p></body></html>
false && * x^.++@; true
"false && true"
希望這些無聊的例子有助於澄清為什么應用您引用源代碼的規則毫無意義。 該規則意味着應用於解析源代碼后產生的值/子樹(此時已應用操作順序)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.