Musiałem napisać procedurę, która zwiększa wartość zmiennej o 1, jeśli jej typ to number
i przypisuje 0 do zmiennej, jeśli nie, gdzie zmienna jest początkowo null
lub undefined
.
Pierwsza implementacja była v >= 0 ? v += 1 : v = 0
taka, ponieważ myślałem, że cokolwiek, co nie jest liczbą, spowoduje, że wyrażenie arytmetyczne będzie fałszywe, ale było błędne, ponieważ null >= 0
jest oceniane jako prawda. Potem dowiedziałem null
się, że zachowuje się jak 0 i wszystkie poniższe wyrażenia są oceniane jako prawdziwe.
null >= 0 && null <= 0
!(null < 0 || null > 0)
null + 1 === 1
1 / null === Infinity
Math.pow(42, null) === 1
Oczywiście null
nie null == 0
jest 0 jest oceniane jako fałsz. To sprawia, że pozornie tautologiczne wyrażenie jest (v >= 0 && v <= 0) === (v == 0)
fałszywe.
Dlaczego jest null
jak 0, chociaż w rzeczywistości nie jest to 0?
javascript
null
comparison
equality
C. Lee
źródło
źródło
null
alboundefined
:c = -~c // Results in 1 for null/undefined; increments if already a number
undefined
jest wartością zmiennej dla zmiennych, które nie zostały zainicjowane.null
z drugiej strony jest pustą wartością obiektu i nie należy jej mieszać z liczbami.null
nie powinno być łączone z liczbami, więc null nie powinno zachowywać się jak liczby.Odpowiedzi:
Twoje prawdziwe pytanie brzmi:
Czemu:
Ale:
To, co naprawdę się dzieje, to fakt, że operator Większy lub równy (
>=
) wykonuje wymuszenie typu (ToPrimitive
), z podpowiedzią typuNumber
, w rzeczywistości wszystkie operatory relacyjne mają takie zachowanie.null
jest traktowany w specjalny sposób przez operatora równości (==
). Krótko mówiąc, zmusza tylko doundefined
:Wartość takich jak
false
,''
,'0'
, i[]
podlegają numerycznej typu przymus, wszystkie z nich przymusić do zera.Możesz zobaczyć wewnętrzne szczegóły tego procesu w algorytmie abstrakcyjnego porównania równości i algorytmu abstrakcyjnego porównania relacyjnego .
W podsumowaniu:
Porównanie relacyjne: jeśli obie wartości nie są typu String,
ToNumber
jest wywoływane na obu. To jest to samo, co dodanie z+
przodu, co dla zerowych wymuszeń0
.Porównanie równości: wywołuje tylko
ToNumber
łańcuchy, liczby i wartości logiczne.źródło
null is treated in a special way by the Equals Operator (==). In a brief, it only coerces to undefined:
- a co? Czy możesz wyjaśnić, dlaczegonull >= 0
? :)+
przodu, co dla zerowych wymuszeń0
. Równość wywołuje tylko ToNumber na ciągach, liczbach i logicznych.Chciałbym rozszerzyć pytanie, aby jeszcze bardziej poprawić widoczność problemu:
To po prostu nie ma sensu. Podobnie jak w przypadku ludzkich języków, tych rzeczy trzeba się uczyć na pamięć.
źródło
JavaScript oferuje zarówno ścisłe, jak i konwertujące typy porównań
null >= 0;
jest prawdziwe, ale(null==0)||(null>0)
jest fałszywenull <= 0;
jest prawdziwe, ale(null==0)||(null<0)
jest fałszywe"" >= 0
jest również prawdąW przypadku relacyjnych porównań abstrakcyjnych (<=,> =) operandy są najpierw konwertowane na prymitywy, a następnie na ten sam typ, przed porównaniem.
typeof null returns "object"
Gdy typ jest obiektem, javascript próbuje nadać obiektowi ciąg znaków (tj. Null), podejmowane są następujące kroki ( ECMAScript 2015 ):
PreferredType
nie został przekazany, niechhint
będzie „domyślny”.PreferredType
jest ciągiemhint
, niechhint
będzie „ciągiem”.PreferredType
jesthint
numer, niechhint
będzie „numer”.exoticToPrim
będzieGetMethod(input, @@toPrimitive)
.ReturnIfAbrupt(exoticToPrim)
.exoticToPrim
nie jest niezdefiniowane, toa) Niech wynik będzie
Call(exoticToPrim, input, «hint»)
.b)
ReturnIfAbrupt(result)
.c) Jeśli
Type(result)
nie jest Object, zwraca wynik.d) Zgłoś wyjątek TypeError.
hint
jest „domyślna”, niechhint
będzie „liczbą”.OrdinaryToPrimitive(input,hint)
.Dozwolone wartości podpowiedzi to „default”, „number” i „string”. Obiekty Date są unikalne wśród wbudowanych obiektów ECMAScript, ponieważ traktują „default” jako odpowiednik „string”. Wszystkie inne wbudowane obiekty ECMAScript traktują „default” jako odpowiednik „number” . ( ECMAScript 20.3.4.45 )
Więc myślę, że
null
konwertuje do 0.źródło
Miałem ten sam problem !!. Obecnie moim jedynym rozwiązaniem jest oddzielenie.
źródło
if (a!=null && a>=0)
. To wyjaśnia powód, dla którego nie robisz>=
tego samodzielnie: „a może być zerowe (lub niezdefiniowane, co oznacza również '== null')”.Matematycznie to dziwne. Ostatni wynik stwierdza, że „null jest większe lub równe zero”, więc w jednym z powyższych porównań musi to być prawda, ale oba są fałszywe.
Powodem jest to, że sprawdzanie równości
==
i porównania> < >= <=
działają inaczej. Porównania konwertują wartość null na liczbę, traktując ją jako0
. Dlatego (3)null >= 0
jest,true
a (1)null > 0
jestfalse
.Z drugiej strony, sprawdzenie równości
==
dlaundefined
anull
jest zdefiniowana tak, że bez żadnej konwersji, to równa się wzajemnie i nie robić nic więcej równe. Dlatego (2)null == 0
jestfalse
.źródło