Mały background (może dla innych): używasz tzw. Abstract Equality Comparison – czyli działania operatora ==
(w przeciwieństwie do operatora ===
).
W Twoim kodzie spoon
jest typu Object
, a 0
oraz 1
są typu Number
. Z uwagi na to JavaScript w wyrażeniach spoon == 0
oraz spoon == 1
najpierw przekonwertuje spoon
oraz, odpowiednio, 0
i 1
do tego samego typu przekonwertuje spoon
według tych ściśle zdefiniowanych reguł, a następnie użyje właśnie operatora ===
między wynikami konwersji a, odpowiednio, 0
i 1
**. Dzieje się to u Ciebie zgodnie z następującym cytatem ze strony developer.mozilla.org:
If an object is compared with a number or string, JavaScript attempts to return the default value for the object. Operators attempt to convert the object to a primitive value, a String or Number value, using the valueOf and toString methods of the objects. If this attempt to convert the object fails, a runtime error is generated.
Według tego, jak ten kod wykonuje się u mnie w konsoli Firefoxa, domniemywam, że Ty nie otrzymałeś w wyniku wykonania wspomnianego runtime error, a jedynie wartość undefined
(zamiast oczekiwanej przez Ciebie wartości true
lub wartości false
oczekiwanej przez Ciebie informacji, że łyżka "istnieje" lub "nie istnieje"). Dlaczego undefined
? Twój kod sprawdza abstract equality obiektu spoon
najpierw z 0
, a potem z 1
. Oba porównania zwrócą false
.* Gdybyś miał klauzulę else
, wynik byłby zależny od tego, co w niej jest. Na przykład: else { console.log("Ani 0, ani 1"); }
.
Nie mogę Ci napisać, jak powinno to wyglądać, ponieważ nie napisałeś, czego oczekujesz od tego kodu. Dwie uwagi:
- Moim zdaniem prawie zawsze wartość dodawać klauzulę
else
– choćby tylko z tego powodu, że możesz, jak projektant programu, przeoczyć pewne przypadki. Mając klauzulę else
zawsze otrzymasz zdefiniowaną przez siebie informację, a nie mając – będzie to w tych przypadkach enigmatyczne undefined
. Jeśli rzeczywiście uznasz, że klauzula else
nie ma sensu, to oczywiście jej nie dodawaj.
- Poza wykorzystywanymi przez Ciebie porównaniami: widzę, że nie wykorzystujesz zmiennej
fork
ani właściwości isExist
; może powinieneś?
* To, że oba porównania zwrócą false
, wiem z praktyki – sprawdziłem w konsoli Firefoxa. Podany cytat jest zbyt enigmatyczny, by dokładnie określić zachowanie kodu; z drugiej strony nie studiowałem (jeszcze ;)) standardu ECMAScript, więc dokładnie Ci nie powiem, dlaczego tak jest; tutaj masz odpowiednią sekcję, jeśli kiedyś chciałbyś to zrozumieć: https://www.ecma-international.org/ecma-262/#sec-abstract-equality-comparison
Posłowie. Ja się nauczyłem nie korzystać z operatora ==
, tylko zawsze z ===
; jednak spotkałem się też z tym, że ludzie wolą korzystać z tego pierwszego.
UPDATE:
W zasadzie mogę Ci podpowiedzieć, jak poprawić ten kod. Na pewno nie możesz pisać, że "łyżka istnieje" w żadnym przypadku: ani jak porównujesz z 0
, ani jak porównujesz z 1
. (W obu przypadkach będzie to fałsz, jak wyżej napisałem). Jeśli koniecznie chcesz te porównania mieć/zostawić/robić, to zmień tekst wypisywany na coś takiego:
- w przypadku porównania z
0
-> spoon + " != 0"
;
- w przypadku porównania z
1
-> spoon + " != 1"
.
UPDATE2: Poprawiłem link do wspomnianej sekcji specyfikacji ECMAScript na aktualny (poprzedni był do wersji 5.1 ECMAScript).
UPDATE3:
** Oczywiście popełniłem błąd – prawa strona każdego z porównań nie jest konwertowana, specyfikacja jasno o tym mówi:
If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
false