Obiekty własne w JavaScript

0

Mam do zrobienia takie zadanie:
Do pliku app.js przekopiuj poniższy kod:
const spoon = {    isExist: true }
const fork = spoon; fork.isExist  = false;
Następnie sprawdź czy łyżka istnieje.
No i sprawdzam. Ale nie działa

if(spoon == 0) {
console.log("Łyżka " + spoon + " nie istnieje");
} else if(spoon == 1) {
console.log("Łyżka " + spoon + " istnieje");
}

0

Jeśli spoon jest obiektem to czemu ten obiekt porównujesz z liczbą?

1

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1