2011-07-26 9 views
9

En JavaScript undefined se puede reasignar, por lo que a menudo se recomienda crear una función autoejecutable que asegure que undefined no está definido. Como alternativa, null y undefined son definitivamente == pero ¿hay algún otro valor que sea vagamente equivalente a null/undefined?JavaScript indefinido reemplazado por nulo

TLDR

Básicamente se puede reemplazar con seguridad esto:

(function(undefined){ 

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

})(); 

con:

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

Si lo anterior es 100% seguro, ¿por qué no lo hace la comunidad JavaScript/caen las bibliotecas undefined en total y use el condicional más corto x == null para verificar ambos null/undefined a la vez?

EDIT:

nunca he visto a alguien en realidad representan un "valor desconocido" con 'indefinido' vs null? Nunca he visto este escenario, y es por eso que originalmente hice la pregunta. Simplemente parece ser dos valores increíblemente confusos que nunca se usan en su intención original. Estandarizar todo para hacer una comparación obj==null sería beneficioso para el tamaño y evitaría cualquier problema con la reasignación. Todo seguirá trabajando

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

var x; 
ix==null // true 

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

La única excepción a esta regla parece ser al lanzar undefined/null a un entero. Este es un escenario bonito de edad, pero definitivamente debe tenerse en cuenta.

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

Considerando NaN es el único valor en JavaScript no es igual a sí mismo, usted puede hacer algunas cosas bastante locas como:

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

Usando null como una gota igualdad suelta == en reemplazo de undefined es seguro, siempre que no tenga previsto convertir el valor en un número entero. Lo cual es un escenario muy bonito.

Respuesta

6

El abstract equality algorithm de la sección 11.9.3 de la especificación lenguaje es lo que define == y != y se define de tal manera que ellos

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

donde void 0 es sólo una forma confiable de decir undefined (véase más adelante) por lo que la respuesta a su pregunta es sí, null es igual a indefinido y en sí y nada más.

Las partes pertinentes de la especificación son

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. 
... 

Si usted está preocupado acerca de undefined que significa algo distinto de lo que normalmente significa que, en vez utilizar 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 

Desde el language specification:

11.4.2 El operador void

El UnaryExpression producción: vacíoUnaryExpression se evalúa de la siguiente manera:

  1. Sea expr el resultado de la evaluación de UnaryExpression /.
  2. Llame GetValue(expr).
  3. Retorno undefined.

Así el operador void prefijo evalúa sus argumentos y devuelve el valor especial indefinido independientemente de lo que la variable global undefined se ha cambiado (o si undefined se define :).

EDIT: En respuesta a los comentarios,

Si se trata de código de la biblioteca que distingue entre los dos, entonces usted necesita para hacer frente a la diferencia. Algunas de las nuevas bibliotecas normalizado por el Comité idioma ignorar la diferencia: JSON.stringify([void 0]) === "[null]" pero hay demasiado código por ahí que los trata sutilmente diferente, y hay otras diferencias:

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

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

Si va a escribir cualquier tipo de bibliotecas que producen texto o serializar/deserializar y desea unir las dos, entonces no puede pasar undefined y esperar que se comporte como null - necesita normalizar explícitamente sus entradas a una u otra.

+0

Puede usar 'null' en el código anterior como' void 0'. También podría argumentar que 'null' es un poco más fácil de leer y escribir luego' void 0'. Mi punto es que parece que no tiene ningún valor distinguir entre los dos. Aunque se supone que indefinido representa un "valor desconocido", en realidad nadie se apega a esta convención. Por lo tanto, parece beneficioso ignorar 'undefined' cada uno existente y simplemente usar' obj == null' en su lugar. – William

+0

@Lime, consulte mis ediciones. –

+0

Gracias, no estaba al tanto de cuáles eran los valores cuando se convertían en enteros. Tener 'NaN' vs' 0' es definitivamente diferente. Parece que '[null] .join ('')' y '[undefined] .join ('')' son equivalentes. – William

2

Debido a esto:

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'); 

Cualquier cosa como nulas no está definido - se define como nulo.

+0

Mi punto es que parece que no hay ningún valor para distinguir entre los dos. Aunque se supone que 'indefinido' representa un "valor desconocido", en realidad nadie se apega a esta convención. – William

+0

Suponiendo que nunca se asigna nada a un valor de indefinido, tiene sentido poder diferenciar entre una variable no modificada y una no anulada. Aunque, para todos los propósitos prácticos de cómo JS es utilizado por los desarrolladores hoy en día, puedo ver tu punto ... – Brian

0

lectura Javascript: las partes buenas, parece que sólo nula e indefinido son equivalentes

JavaScript tiene dos grupos de operadores de igualdad: === == y, y sus gemelos del mal == y! =. Los buenos funcionan de la manera esperable. Si los dos operandos son del mismo tipo y tienen el mismo valor, entonces === produce verdadero y! == produce falso. Los gemelos malignos hacen lo correcto cuando los operandos son del mismo tipo , pero si son de tipos diferentes, intentan coaccionar los valores.Las reglas por las cuales hacen eso son complicadas y no son memorables. Estos son algunos de los casos interesantes:

'' == '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:. Las partes buenas de Douglas Crockford Copyright 2008 Yahoo! Inc., 978-0-596-51774-8".

+0

El último es horrendo – William

4

Debido Javascript ambos valores. Y aunque otros idiomas solo pueden tener nil/null JavaScript creció con undefined siendo el "valor desconocido", mientras que null es claramente un valor conocido para no representar nada.

Compare var x donde x no está definida porque ningún valor ha sido asignado y var y = null donde y es null. Estaba configurado para algo: un fraseo que representa "nada". Este núcleo uso fundamental de undefined vs null en JavaScript es muy profundo y otros casos incluyen:

  1. Una falta (o delete 'd) establecimiento también producir undefined y no null (que se traduciría en null sólo si null habían sido asignado).
  2. parámetros de función sin asignar son undefined.
  3. undefined devuelto desde funciones estándar como getElementById. Ver comentarios.

Por lo tanto, en Javascript , a menudo es más correcto utilizar undefined y no null. Ambos representan cosas diferentes. Una biblioteca que intenta luchar contra esto está luchando contra JavaScript.

Happy coding.


En lo personal, en casi todos los casos que evitar una comprobación explícita para undefined o null. Creo que en la mayoría de los casos, pero no en todos, todos los valores falsos deben ser equivalentes y que es responsabilidad de los comunicantes cumplir con el contrato público establecido.

Debido a esta creencia que yo consideraría la comparación x == null a punto de tratar de proteger demasiado y sin embargo muy poco, pero en el caso de la captura de nulloundefined, funciona, como se ha señalado. Ir iniciar una tendencia ;-)

+1

métodos DOM como 'getElementById' return' null' porque la noción de 'undefined' no es presente en [WebIDL] (http://www.w3.org/TR/WebIDL/), hay un tipo 'nulo 'en la especificación, pero se usa solo para operaciones que no generan ningún valor. – CMS

+0

Una buena respuesta, también agregaría: 'delete' produce un resultado diferente (' undefined') que '= null'. – Nicole

+0

¿Con qué frecuencia las personas representan intencionalmente un "valor desconocido" con "indefinido"? Nunca he visto este escenario, y es por eso que originalmente hice la pregunta.Simplemente parece ser dos valores increíblemente confusos que nunca se usan en su intención original. Estandarizar todo para hacer una comparación 'obj == null' sería beneficioso para el tamaño y evitaría cualquier problema con la reasignación. Todo continuaría funcionando 'var obj = {}; obj.nonExistantProperty == null'. 'var x; if (x == null);' – William

Cuestiones relacionadas