2011-07-26 23 views
9

W JavaScript undefined można ponownie przypisać, dlatego często zaleca się utworzenie funkcji self executing, która zapewnia, że ​​undefined jest rzeczywiście niezdefiniowany. Alternatywnie, null i undefined są zdecydowanie ==, ale czy są jakieś inne wartości luźno równoważne z null/undefined?JavaScript undefined zastąpiony wartością null

TLDR

Zasadniczo można bezpiecznie zastąpić to:

(function(undefined){ 

    window.f = function(obj){ 
    if(obj===undefined || obj===null){ 
     alert('value is undefined or null'); 
    } 
    } 

})(); 

z:

window.f = function(obj){ 
    if(obj==null){ 
    alert('value is undefined or null'); 
    } 
} 

Jeśli powyższe jest w 100% bezpieczne, to dlaczego nie wspólnota JavaScript/biblioteki upuść undefined w ogóle i użyć krótszego warunku, aby od razu sprawdzić oba atrybuty: null/?

EDIT:

Nigdy nie widziałem kogoś faktycznie stanowią "nieznaną wartość" z 'niezdefiniowane' vs null? Nigdy nie widziałem tego scenariusza i dlatego pierwotnie zadałem to pytanie. Wydaje się, że są to dwie niewiarygodnie zdezorientowane wartości, które nigdy nie są używane w pierwotnym zamyśle. Standaryzacja wszystkiego w celu porównania obj==null byłaby korzystna dla rozmiaru i uniknięcia problemów z ponownym przypisaniem. Wszystko będzie nadal pracować

var obj={}; 
obj.nonExistantProperty==null // true 

var x; 
ix==null // true 

function(obj){ 
    obj==null // true 
} 

Jedynym wyjątkiem od tej reguły wydaje się być przy odlewaniu undefined/null do liczby całkowitej. Jest to całkiem odpowiedni scenariusz wiekowy, ale na pewno należy go odnotować.

+(null)==0 podczas isNaN(+undefined)

Zważywszy NaN jest jedyną wartością w JavaScript nie jest równe sobie, można zrobić pewne dość szalone rzeczy, jak:

+undefined == +undefined // false 
+null == +null // true 

Korzystanie null jako luźny równość == spadku zamiennik dla undefined jest bezpieczny, pod warunkiem, że nie planujesz rzutowania wartości na liczbę całkowitą. Co jest scenariuszem całkiem nielicznych przypadków.

Odpowiedz

6

abstract equality algorithm z sekcji 11.9.3 w specyfikacji języka jest to, co definiuje == i != i określa je w taki sposób,

null == void 0 
null == null 
void 0 == null 

void 0 gdzie jest po prostu niezawodny sposób mówienia undefined (patrz poniżej), więc odpowiedź na twoje pytanie brzmi: tak, null jest równa niezdefiniowana i sama w sobie i nic więcej.

Odpowiednie części specyfikacji są

1. If Type(x) is the same as Type(y), then 
    If Type(x) is Undefined, return true. 
    If Type(x) is Null, return true. 
    ... 
2. If x is null and y is undefined, return true. 
3. If x is undefined and y is null, return true. 
... 

Jeśli martwisz się o undefined oznacza coś innego niż to, co zwykle oznacza, zamiast używać void 0.

null    == void 0   // True 
({}).x    === void 0   // True 
"undefined"  === typeof void 0 // True 
(function() {})() === void 0   // True 
(undefined = 42, 
undefined   === void 0)   // False 
"undefined"  === typeof undefined // False 
"undefined"  === typeof void 0 // True 

Z language specification:

11.4.2 Pustka Operator

UnaryExpression produkcja: voidUnaryExpression oceniana jest następująco:

  1. Niech expr będzie wynikiem oceny UnaryExpression /.
  2. Zadzwoń pod GetValue(expr).
  3. Powrót undefined.

Więc operator void prefiks ocenia swój argument i zwraca wartość szczególną niezdefiniowany niezależnie od tego co zmienna globalna undefined została zmieniona (czy undefined definiuje :).

EDIT: W odpowiedzi na komentarze,

Jeśli masz do czynienia z kodem biblioteki, który odróżnia między nimi, to trzeba do czynienia z różnicą. Niektóre z nowych bibliotek standaryzowanych przez komisję języka ignoruj ​​różnicę: JSON.stringify([void 0]) === "[null]" ale nie ma zbyt wiele kod tam, że traktuje je subtelnie inaczej, a są jeszcze inne różnice:

+(null) === 0 
isNaN(+undefined) 

"" + null === "null" 
"" + undefined === "undefined" 

Jeśli piszesz wszelkiego rodzaju bibliotek, które produkują tekst lub serializują/deserializują i chcesz je połączyć, wtedy nie możesz przejść przez undefined i oczekiwać, że będzie się zachowywać jak null - musisz jawnie znormalizować swoje dane wejściowe do jednego lub drugiego.

+0

Równie dobrze można użyć 'null' w powyższym kodzie, używając' void 0'. Mogę również argumentować, że 'null' jest nieco łatwiejsze do odczytania i wpisz' void 0'. Chodzi mi o to, że wydaje się, że nie ma żadnej wartości w rozróżnianiu między nimi. Chociaż niezdefiniowane ma reprezentować "nieoszacowaną wartość", nikt nie trzyma się tej konwencji. Tak więc korzystne byłoby zignorowanie 'undefined' każdego istniejącego i po prostu użycie' obj == null' w jego miejsce. – William

+0

@Lime, zobacz moje zmiany. –

+0

Dzięki, nie byłem świadomy, jakie wartości były, gdy są rzutowane na liczby całkowite. Posiadanie 'NaN' vs' 0' jest zdecydowanie inne. Wygląda na to, że '[null] .join ('')' i '[undefined] .join ('')' są równoważne. – William

2

z tego powodu:

var myVar1; 
var myVar2 = null; 

if (myVar1 === null) alert('myVar1 is null'); 
if (myVar1 === undefined) alert('myVar1 is undefined'); 
if (myVar2 === null) alert('myVar2 is null'); 
if (myVar2 === undefined) alert('myVar2 is undefined'); 

Wszystko ustawione na null nie jest nieokreślona - jest zdefiniowana jako null.

+0

Mój punkt jest taki, że wydaje się, że nie ma żadnej wartości w rozróżnieniu między nimi. Chociaż 'undefined' ma reprezentować" nieokreśloną wartość ", nikt nie trzyma się tej konwencji. – William

+0

Zakładając, że nigdy nie przypisujesz niczego do wartości nieokreślonej, istnieje możliwość odróżnienia zmiennej nietkniętej od unieważnionej. Chociaż, ze wszystkich praktycznych powodów, w jaki sposób JS jest używane przez dzisiejszych programistów, widzę twój punkt widzenia ... – Brian

0

Reading JavaScript: The Good części, wydaje się, że tylko wartości null i undefined są równoważne

JavaScript ma dwa zestawy operatorów równości: === i ==, a ich złe bliźniaki == i! =. Ci dobrzy działają tak, jak można by oczekiwać. Jeśli oba operandy są tego samego typu i mają tę samą wartość, to === daje wartość true, a! == powoduje fałsz. Złe bliźnięta robią dobrze, gdy operandy są tego samego typu, ale jeśli są różnych typów, próbują wymusić wartości.Zasady, według których robią to, są skomplikowane i niezapomniane. Są to jedne z ciekawszych przypadkach:

'' == '0' // false 
0 == '' // true 
0 == '0' // true 
false == 'false' // false 
false == '0' // true 
false == undefined // false 
false == null // false 
null == undefined // true 
' \t\r\n ' == 0 // true 

"JavaScript.. The Good Parts Douglas Crockforda Copyright 2008 Yahoo! Inc., 978-0-596-51774-8"

+0

Ostatni jest przerażający – William

4

Ponieważ JavaScript ma obie wartości. I podczas gdy inne języki mogą mieć tylko nil/null JavaScript wyrósł z undefined będącym "nieznaną wartością", podczas gdy null jest wyraźnie znaną wartością nic nie reprezentującą.

Porównaj var x gdzie x jest nieokreślona, ​​ponieważ wartość nie została przypisana i var y = null gdzie y jest null. Zostało nastawione na coś - zdanie reprezentujące "nic". Ten rdzeń fundamentalny wykorzystanie undefined vs null w JavaScript działa bardzo głęboko i inne przypadki obejmują:

  1. A („d lub delete) nieruchomość brakuje również wydajność undefined i nie null (spowodowałoby to null tylko jeśli null było przydzielony).
  2. Nieprzypisane parametry funkcji to undefined.
  3. undefined wrócił ze standardowych funkcji, takich jak getElementById. Zobacz komentarze.

Zatem w JavaScript, często jest bardziej poprawne użycie undefined i nie null. Oboje reprezentują różne rzeczy. Biblioteką, która próbuje walczyć z tym jest walka z JavaScript.

Szczęśliwe kodowanie.


Osobiście, w prawie wszystkich przypadkach uniknąć wyraźnego czek na undefined lub null. Uważam, że w większości - ale nie we wszystkich przypadkach - wszystkie fałszywe wartości powinny być równoważne i że obowiązkiem osób dzwoniących jest zgodność z zawartym zamówieniem publicznym.

powodu tej wiary chciałbym rozważyć porównanie x == null na skraju próbuje pilnować zbyt wiele, a jeszcze za mało, ale w przypadku łapania nulllubundefined, to działa, jak wskazano. Idź rozpocząć trend ;-)

+1

Metody DOM, takie jak 'getElementById' zwracają' null' ponieważ pojęcie 'niezdefiniowane' nie jest obecny w [WebIDL] (http://www.w3.org/TR/WebIDL/), istnieje typ "void" w specyfikacji, ale jest używany tylko do operacji, które nie dają żadnej wartości. – CMS

+0

Dobra odpowiedź, dodałaby również: "delete" daje inny wynik ('undefined') niż' = null'. – Nicole

+0

Jak często ludzie celowo reprezentują "nieznaną wartość" za pomocą "niezdefiniowanej"? Nigdy nie widziałem tego scenariusza i dlatego pierwotnie zadałem to pytanie.Wydaje się, że są to dwie niewiarygodnie zdezorientowane wartości, które nigdy nie są używane w pierwotnym zamyśle. Standaryzacja wszystkiego w celu porównania 'obj == null' będzie korzystna dla rozmiaru i uniknie problemów z ponownym przypisaniem. Wszystko będzie działało nadal "var obj = {}; obj.nonExistantProperty == null'. 'var x; if (x == null);' – William

Powiązane problemy