簡體   English   中英

為什么`false && true || 真的`評價為真嗎?

[英]Why does `false && true || true` evaluate to true?

根據MDN Logical Operators頁面:

false &&任何短路評估為假。

鑒於此信息,我希望false && true || true false && true || true評估為false則為true。 然而,這種情況並非如此。 只有當語句寫成如下時,才會給出預期結果( false ):

false && (true || true)

一位同事和我試圖解決這個問題,我們可以提出的最接近的事情就是按照優先順序評估該聲明。 根據MDN運算符優先級 logical-andlogical-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僅適用於有效的子樹,其中falseanything都是&& 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

就短路而言,如果Afalse ,可以縮短的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 || truefalse相比,只考慮第一個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.

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