org - ¿Cómo utilizo el operador existencial de CoffeeScript para verificar algunas propiedades de los objetos en busca de undefined?
hentry wordpress (3)
Conjetura salvaje ¿has probado console.log test.test if test?.test?
?
Solo lo probé con coffee -p -e ''console.log test.test if test?.test?''
, que compila a:
(función () {
if ((typeof test! == "undefined" && test! == null? test.test: void 0)! = null) {console.log (test.test); }
}).llama esto);
Me gustaría usar el operador existencial de CoffeeScript para verificar algunas propiedades de los objetos en busca de undefined. Sin embargo, me encontré con un pequeño problema.
Código como este:
console.log test if test?
Compila a:
if (typeof test !== "undefined" && test !== null) console.log(test);
Cuál es el comportamiento que me gustaría ver. Sin embargo, cuando intento usarlo contra propiedades de objeto, como esto:
console.log test.test if test.test?
Me sale algo así:
if (test.test != null) console.log(test.test);
Que no parece un cheque contra indefinido en absoluto. La única forma en que podría haber logrado el mismo comportamiento (1: 1) que usándolo para los objetos fue usando un cheque más grande:
console.log test.test if typeof test.test != "undefined" and test.test != null
La pregunta es: ¿Estoy haciendo algo mal? ¿O es el código compilado lo suficiente para verificar la existencia de una propiedad (un cheque nulo con conversión de tipo)?
Este JavaScript:
a.foo != null
en realidad comprueba si la propiedad foo
de a
no es undefined
ni null
. Tenga en cuenta que a.foo?
se traduce a JavaScript que utiliza != null
lugar de !== null
. Las conversiones que hace !=
significa que ambas son verdaderas:
null == null
undefined == null
Una llanura a?
se convierte en este JavaScript:
typeof a !== "undefined" && a !== null
Porque hay tres condiciones para comprobar:
- ¿Hay alguna en alcance en
a
lugar? - ¿Tiene un valor de
undefined
? - ¿Tiene un valor
null
?
La primera condición es importante, ya que simplemente decir que a != null
activará un error de referencia si no hay a
alcance en el alcance, pero decir que typeof a === ''undefined''
no lo hará. El tipo de comprobación también se ocupa de la condición a a === undefined
en 2 . Luego, podemos terminar con una prueba a !== null
estricta de a !== null
ya que se ocupa de 3 sin la penalización de rendimiento de una innecesaria !=
(Nota !=
Y ==
son más lentas que !==
y ===
debido a las conversiones implícitas).
Una pequeña lectura sobre qué !=
Y !==
hacer puede ser fructífera:
En lo que respecta a su comentario sobre la respuesta eliminada, if(a.foo)
tiene una sintaxis perfectamente válida si completa la declaración if
:
if(a.foo)
do_interesting_things()
# or
do_interesting_things() if(a.foo)
Sin embargo, if(a.foo)
y if(a.foo?)
Difieren en la forma en que manejan 0
, false
y ''''
.
Este es un punto de confusión común con el operador existencial: a veces
x?
compila a
typeof test !== "undefined" && test !== null
y otras veces simplemente compila
x != null
Los dos son equivalentes, porque x != null
será false
cuando x
sea null
o undefined
. Entonces, x != null
es una forma más compacta de expresar (x !== undefined && x !== null)
. La razón por la que se produce el tipo de compilación es que el compilador piensa que x
puede que no se haya definido en absoluto, en cuyo caso, al hacer una prueba de igualdad se activaría ReferenceError: x is not defined
.
En su caso particular, test.test
puede tener el valor undefined
, pero no puede obtener un ReferenceError
refiriéndose a una propiedad no definida en un objeto existente, por lo que el compilador opta por la salida más corta.