El diseño del lenguaje Javascript no es lo suficientemente riguroso y pueden ocurrir errores en muchos lugares si no se tiene cuidado.
Por ejemplo, considere la siguiente situación.
Ahora, necesitamos determinar si existe un objeto global myObj. Si no existe, declararlo. El algoritmo descrito en lenguaje natural es el siguiente:
Copie el código de código de la siguiente manera:
si (miObj no existe){
declarar miObj;
}
Podría pensar que escribir este código es fácil. Pero, de hecho, las cuestiones gramaticales involucradas son mucho más complejas de lo que imaginamos. Juriy Zaytsev señaló que existen más de 50 formas de determinar si un objeto Javascript existe. Sólo si tiene muy claros los detalles de implementación del lenguaje Javascript podrá notar la diferencia entre ellos.
La primera forma de escribir.
Intuitivamente, podrías pensar que podrías escribir:
Copie el código de código de la siguiente manera:
si (!miObj) {
miObj = { };
}
Sin embargo, al ejecutar este código, el navegador arrojará directamente un error ReferenceError, lo que provocará que se interrumpa la operación. ¿Qué ocurre?
Por cierto, cuando la declaración if determina si myObj está vacío, la variable aún no existe, por lo que se informa un error. Cámbielo a lo siguiente y se ejecutará correctamente.
Copie el código de código de la siguiente manera:
si (!miObj) {
var miObj = { };
}
¿Por qué no aparece ningún error después de agregar una var? ¿Podría ser que en este caso, cuando la declaración if emite un juicio, myObj ya existe?
Para responder a esta pregunta, debes saber cómo funciona el intérprete de Javascript. El lenguaje Javascript es "analizar primero, ejecutar después". La declaración de variable ya se completó durante el análisis, por lo que el código anterior en realidad es equivalente a:
Copie el código de código de la siguiente manera:
var miObj;
si (!miObj) {
var miObj = { };
}
Por lo tanto, cuando la declaración if emite un juicio, myObj ya existe, por lo que no se informa ningún error. Este es el efecto de "elevación" del comando var. El intérprete de Javascript solo "promueve" variables definidas por el comando var y no funciona con variables asignadas directamente sin usar el comando var. Es por eso que se informará un error si no se agrega var.
La segunda forma de escribir.
Además del comando var, hay otra reescritura que también puede obtener resultados correctos:
Copie el código de código de la siguiente manera:
si (!ventana.miObj) {
miObj = { };
}
Window es el objeto de nivel superior de JavaScript y todas las variables globales son sus propiedades. Por lo tanto, determinar si myobj está vacío es equivalente a determinar si el objeto de ventana tiene el atributo myobj, de modo que se puedan evitar los errores de ReferenceError que ocurren porque myObj no está definido. Sin embargo, desde la estandarización del código, es mejor agregar var a la segunda línea:
Copie el código de código de la siguiente manera:
si (!ventana.miObj) {
var miObj = { };
}
O escrito así:
si (!ventana.miObj) {
ventana.myObj = { };
}
La tercera forma de escribir.
La desventaja del método de escritura anterior es que en algunos entornos en ejecución (como V8, Rhino), es posible que la ventana no sea un objeto de nivel superior. Entonces, considere reescribirlo como:
Copie el código de código de la siguiente manera:
si (!this.myObj) {
this.myObj = { };
}
En el nivel de variables globales, la palabra clave this siempre apunta a la variable de nivel superior, por lo que puede ser independiente de diferentes entornos de ejecución.
La cuarta forma de escribir.
Sin embargo, la forma de escritura anterior es menos legible y el puntero de esto es variable y propenso a errores, por lo que lo reescribimos aún más:
Copie el código de código de la siguiente manera:
var global = esto;
si (!global.miObj) {
global.miObj = { };
}
Es mucho más claro utilizar la variable personalizada global para representar el objeto de nivel superior.
La quinta forma de escribir.
También puede utilizar el operador typeof para determinar si myObj está definido.
Copie el código de código de la siguiente manera:
if (tipo de miObj == "indefinido") {
var miObj = { };
}
Este es actualmente el método más utilizado para determinar si existe un objeto JavaScript.
La sexta forma de escribir.
Dado que el valor de myObj es directamente igual a indefinido cuando está definido pero no asignado, el método de escritura anterior se puede simplificar:
Copie el código de código de la siguiente manera:
si (miObj == indefinido) {
var miObj = { };
}
Hay dos cosas a tener en cuenta aquí. En primer lugar, la palabra clave var en la segunda línea no puede faltar; de lo contrario, se producirá un error de referencia. En segundo lugar, no se puede agregar indefinido con comillas simples o dobles, porque aquí se compara el tipo de datos de indefinido. no "indefinido" Esta cadena.
La séptima forma de escribir.
El método de escritura anterior sigue siendo válido en el caso de "comparación exacta" (===):
Copie el código de código de la siguiente manera:
si (miObj === indefinido) {
var miObj = { };
}
La octava forma de escribir.
Según el diseño del lenguaje JavaScript, indefinido == nulo, por lo que comparar si myObj es igual a nulo también puede obtener el resultado correcto:
Copie el código de código de la siguiente manera:
si (miObj == nulo) {
var miObj = { };
}
Sin embargo, aunque los resultados de la ejecución son correctos, desde un punto de vista semántico, este método de juicio es incorrecto y debe evitarse. Porque nulo se refiere a un objeto vacío al que se le ha asignado un valor nulo, es decir, este objeto en realidad tiene un valor, mientras que indefinido se refiere a un objeto que no existe o no tiene ningún valor asignado. Por lo tanto, aquí solo se puede utilizar el "operador de comparación" (==). Si aquí se utiliza el "operador de comparación exacto" (===), se producirá un error.
La novena forma de escribir.
También puede utilizar el operador in para determinar si myObj es un atributo del objeto de nivel superior:
Copie el código de código de la siguiente manera:
if (!('myObj' en la ventana)) {
ventana.myObj = { };
}
La décima forma de escribir.
Finalmente, use el método hasOwnProperty para determinar si myObj es una propiedad del objeto de nivel superior:
Copie el código de código de la siguiente manera:
if (!this.hasOwnProperty('miObj')) {
this.myObj = { };
}
Resumir
1. Si solo determina si el objeto existe, se recomienda utilizar el quinto método de escritura.
2. Si además de si el objeto existe, también necesita determinar si el objeto tiene un valor nulo, se recomienda utilizar la primera forma de escritura.
3. A menos que existan circunstancias especiales, todas las variables deben declararse mediante el comando var.
4. Para que sea multiplataforma, se recomienda evitar el uso de ventanas para representar objetos de nivel superior.
5. En el lenguaje Javascript, nulo e indefinido se confunden fácilmente. En los casos en que ambos puedan estar involucrados, se recomienda utilizar el operador de "comparación exacta" (===).