2017-08-11 22 views
17

Dlaczego w przypadku konsoli JavaScript Chrome w instrukcji nawiasów {} - 0 zmieniana jest zwracana wartość?{} - 0 VS ({} - 0) w JavaScript

{} - 0 // Returns -0 
({} - 0) // Returns NaN 

Wydaje się niezwykle dziwne, że zawijanie pojedynczej instrukcji w nawiasie zmienia wartość. Czego tu mi brakuje?

+0

Dobre pytanie, na pewno są inni o wiele bardziej doświadczeni niż ja. Sądzę, że ma to związek z faktem, że owijasz go w parantezę, co czyni go funkcją wykonywalną automatycznie? – jdmdevdotnet

+2

https://www.destroyallsoftware.com/talks/wat –

+1

Postrzegany jako pusty blok, kontra pusty obiekt – epascarello

Odpowiedz

19

Istnieją dwie możliwe interpretacje linii {} - 0:

  1. To może być interpretowane jako {}; -0, gdzie {} jest interpretowane jako pusta instrukcja blokowa, a - jest jednoargumentowym operatorem negacji (więc -0 jest po prostu "ujemnym zerem"). Wartością tego przy ocenie jest wartość ostatniej instrukcji, która wynosi -0.
  2. może to być interpretowane jako ({} - 0), gdzie {} interpretowana jest jako pusta obiektu i - jest operatorem odejmowania (tak 0 jest odejmowany od {}).

W pierwszym wierszu jest to niejednoznaczne, więc wybierze pierwszą interpretację. W drugim wierszu pierwsza interpretacja jest nieważna (ponieważ instrukcja bloku nigdy nie może być częścią wyrażenia, które wymuszasz na parantezach).

+4

To jest bardzo interesujące pytanie.Nie OP, ale mam do tego następującą odpowiedź: co, jeśli wymusisz interpretację '{}' jako obiektu przez dodanie metody lub właściwości? Działa to z nawiasem, ale nie bez. (np. z nawiasami, to wyrażenie jest oceniane na '3':' ({valueOf:() => 3} - 0) ', ale bez, wciąż zwraca' -0' w konsoli: '{valueOf :() => 3} - 0 "). Czy dodana metoda nie powinna zmusić go do interpretacji '{..}' jako obiektu w tym punkcie, a następnie spróbować ocenić to jako odejmowanie? –

+0

@JosephMarikle Myślę, że to samo rozumowanie nadal obowiązuje, bez parens, nadal może być interpretowane jako '{valueOf:() => 3}; -0' jednak '({valueOf:() => 3}; -0)' jest błędem składni. –

+6

@JosephMarikle Myślisz, że tak, ale nie: "valueOf:" jest w tym przypadku [oświadczeniem etykiety] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) (rzadka funkcja JavaScript) przed instrukcją '() => 3;', więc nadal jest interpretowana jako instrukcja blokowa zamiast obiektu. Jest interpretowany w taki sam sposób, jak '{valueOf:() => 3; }; -0'. – Frxstrem

4

{} - 0: tutaj {} to tylko pusty blok, który nie robi nic, więc -0 zwracane przez konsolę.

({} - 0): tutaj {} jest częścią wyrażenia i jest konwertowany na liczbę. W tym pustym obiekcie nie została zdefiniowana metoda valueOf(), a podczas konwersji na liczbę, powraca ona do metody toString(), która zwraca wartość podobną do object Object dla {}. Następnie ten ciąg object Object jest konwertowany na liczbę i daje NaN, ponieważ w rzeczywistości nie jest liczbą. Tak, mamy

({} - 1) ->('object Object' - 1) ->(NaN - 1)

i wszystko z NaN daje NaN. Właśnie to widać w konsoli.

2
{} - 0 

jest interpretowany: {} empty block statement i - 0 negative zero

({} - 0) 

wszystko wewnątrz () jest interpretowane jako wyraz, empty object - 0 = NaN

Powiązane problemy