w3schools script explícame entre diferencias diferencia javascript

explícame - ¿Diferencia entre las sintaxis de declaración de variables en Javascript(incluidas las variables globales)?



let en jquery (5)

¿Hay alguna diferencia entre declarar una variable:

var a=0; //1

...de esta manera:

a=0; //2

...o:

window.a=0; //3

en alcance global?


Basada en la excelente respuesta de TJ Crowder : ( Fuera del tema: Evite el desorden de la window )

Este es un ejemplo de su idea:

Html

<!DOCTYPE html> <html> <head> <script type="text/javascript" src="init.js"></script> <script type="text/javascript"> MYLIBRARY.init(["firstValue", 2, "thirdValue"]); </script> <script src="script.js"></script> </head> <body> <h1>Hello !</h1> </body> </html>

init.js (Basado en esta respuesta )

var MYLIBRARY = MYLIBRARY || (function(){ var _args = {}; // private return { init : function(Args) { _args = Args; // some other initialising }, helloWorld : function(i) { return _args[i]; } }; }());

script.js

// Here you can use the values defined in the html as if it were a global variable var a = "Hello World " + MYLIBRARY.helloWorld(2); alert(a);

Aquí está el plnkr . Espero que te ayude!


En el ámbito global no hay diferencia semántica.

Pero realmente debe evitar a=0 ya que establece un valor para una variable no declarada.

También use cierres para evitar la edición de alcance global en absoluto

(function() { // do stuff locally // Hoist something to global scope window.someGlobal = someLocal }());

Siempre use cierres y siempre eche el alcance global cuando sea absolutamente necesario. Debería utilizar el manejo asíncrono de eventos para la mayoría de sus comunicaciones de todos modos.

Como mencionó @AvianMoncellor, hay un error de IE con var a = foo solo declara un global para el alcance del archivo. Este es un problema con el notorio intérprete roto de IE. Este error suena familiar por lo que probablemente sea cierto.

Así que window.globalName = someLocalpointer a window.globalName = someLocalpointer


Manteniéndolo simple:

a = 0

El código anterior da una variable de alcance global

var a = 0;

Este código le dará una variable para ser usada en el alcance actual, y debajo de ella

window.a = 0;

Esto generalmente es lo mismo que la variable global.


Sí, hay un par de diferencias, aunque en términos prácticos no suelen ser grandes.

Hay una cuarta vía, y a partir de ES2015 (ES6) hay dos más. He agregado la cuarta forma al final, pero inserté las formas ES2015 después del # 1 (verás por qué), así que tenemos:

var a = 0; // 1 let a = 0; // 1.1 (new with ES2015) const a = 0; // 1.2 (new with ES2015) a = 0; // 2 window.a = 0; // 3 this.a = 0; // 4

Esas declaraciones explicadas

# 1 var a = 0;

Esto crea una variable global que también es una propiedad del objeto global , al que accedemos como window en los navegadores (o, a través de this un alcance global, en código no estricto). A diferencia de otras propiedades, la propiedad no se puede eliminar a través de delete .

En términos de especificación, crea un enlace de identificador en el Registro de entorno de objeto para el entorno global . Eso lo convierte en una propiedad del objeto global porque el objeto global es donde se mantienen los enlaces de identificador para el Registro de entorno del objeto del entorno global. Esta es la razón por la cual la propiedad no se puede eliminar: no es solo una propiedad simple, es un enlace de identificador.

El enlace (variable) se define antes de que se ejecute la primera línea de código (consulte "Cuando ocurre var " más adelante).

Tenga en cuenta que en IE8 y versiones anteriores, la propiedad creada en la window no se puede enumerar (no se muestra en for..in declaraciones for..in ). En IE9, Chrome, Firefox y Opera, es enumerable.

# 1.1 let a = 0;

Esto crea una variable global que no es una propiedad del objeto global. Esto es algo nuevo a partir de ES2015.

En términos de especificación, crea un enlace de identificador en el Registro de entorno declarativo para el entorno global en lugar del Registro de entorno de objeto . El entorno global es único al tener un Registro de entorno dividido, uno para todas las cosas antiguas que van en el objeto global (el Registro de entorno del objeto ) y otro para todas las cosas nuevas ( let , const y las funciones creadas por class ) no vayas en el objeto global.

El enlace se crea antes de que se ejecute cualquier código paso a paso en su bloque adjunto (en este caso, antes de que se ejecute cualquier código global), pero no es accesible de ninguna manera hasta que la ejecución paso a paso alcance la instrucción let . Una vez que la ejecución alcanza la sentencia let , la variable es accesible. (Ver "Cuando suceden let y const " a continuación).

# 1.2 const a = 0;

Crea una constante global, que no es una propiedad del objeto global.

const es exactamente igual a let excepto que debe proporcionar un inicializador (la parte = value ), y no puede cambiar el valor de la constante una vez que se crea. Debajo de las coberturas, es exactamente igual let pero con un indicador en el enlace de identificador que dice que su valor no se puede cambiar. Usar const hace tres cosas para ti:

  1. Hace un error de tiempo de análisis si intenta asignar a la constante.
  2. Documenta su naturaleza inmutable para otros programadores.
  3. Permite que el motor de JavaScript se optimice sobre la base de que no cambiará.

# 2 a = 0;

Esto crea una propiedad en el objeto global de forma implícita . Como es una propiedad normal, puedes borrarlo. Recomiendo no hacer esto, puede ser poco claro para alguien que lea su código más adelante.

Y curiosamente, de nuevo en IE8 y versiones anteriores, la propiedad creada no es enumerable (no aparece en for..in declaraciones for..in ). Eso es extraño, especialmente dado el # 3 a continuación.

# 3 window.a = 0;

Esto crea una propiedad en el objeto global explícitamente, utilizando la window global que se refiere al objeto global (en los navegadores; algunos entornos que no son de navegador tienen una variable global equivalente, como global en NodeJS). Como es una propiedad normal, puedes borrarlo.

Esta propiedad es enumerable, en IE8 y anteriores, y en todos los demás navegadores que he probado.

# 4 this.a = 0;

Exactamente como el # 3, excepto que estamos haciendo referencia al objeto global a través de this lugar de a la window global. Sin embargo, esto no funcionará en modo estricto, porque en el código global en modo estricto, no tiene una referencia al objeto global (en su lugar, el valor undefined ).

Borrando propiedades

¿Qué quiero decir con "eliminar" o "eliminar" a ? Exactamente eso: Eliminando la propiedad (en su totalidad) a través de la palabra clave delete :

window.a = 0; display("''a'' in window? " + (''a'' in window)); // displays "true" delete window.a; display("''a'' in window? " + (''a'' in window)); // displays "false"

delete completamente elimina una propiedad de un objeto. No puedes hacer eso con las propiedades agregadas a la window indirectamente a través de var , la delete se ignora silenciosamente o lanza una excepción (dependiendo de la implementación de JavaScript y de si estás en modo estricto).

Advertencia : IE8 nuevamente (y presumiblemente anterior, e IE9-IE11 en el modo de "compatibilidad" rota): no le permitirá eliminar las propiedades del objeto de la window , incluso cuando se le permita hacerlo. Peor aún, lanza una excepción cuando lo intentas ( prueba este experimento en IE8 y en otros navegadores). Así que al eliminar del objeto de la window , tienes que estar a la defensiva:

try { delete window.prop; } catch (e) { window.prop = undefined; }

Eso intenta eliminar la propiedad, y si se lanza una excepción, hace la siguiente mejor opción y establece la propiedad como undefined .

Esto solo se aplica al objeto de la window , y solo (hasta donde sé) a IE8 y anteriores (o IE9-IE11 en el modo de "compatibilidad" rota). Otros navegadores están bien con la eliminación de window propiedades de la window , sujeto a las reglas anteriores.

Cuando var sucede

Las variables definidas a través de la instrucción var se crean antes de que se ejecute cualquier código paso a paso en el contexto de ejecución, por lo que la propiedad existe mucho antes de la instrucción var .

Esto puede ser confuso, así que echemos un vistazo:

display("foo in window? " + (''foo'' in window)); // displays "true" display("window.foo = " + window.foo); // displays "undefined" display("bar in window? " + (''bar'' in window)); // displays "false" display("window.bar = " + window.bar); // displays "undefined" var foo = "f"; bar = "b"; display("foo in window? " + (''foo'' in window)); // displays "true" display("window.foo = " + window.foo); // displays "f" display("bar in window? " + (''bar'' in window)); // displays "true" display("window.bar = " + window.bar); // displays "b"

Ejemplo en vivo:

display("foo in window? " + (''foo'' in window)); // displays "true" display("window.foo = " + window.foo); // displays "undefined" display("bar in window? " + (''bar'' in window)); // displays "false" display("window.bar = " + window.bar); // displays "undefined" var foo = "f"; bar = "b"; display("foo in window? " + (''foo'' in window)); // displays "true" display("window.foo = " + window.foo); // displays "f" display("bar in window? " + (''bar'' in window)); // displays "true" display("window.bar = " + window.bar); // displays "b" function display(msg) { var p = document.createElement(''p''); p.innerHTML = msg; document.body.appendChild(p); }

Como puede ver, el símbolo foo se define antes de la primera línea, pero la bar símbolos no lo está. Donde la var foo = "f"; declaración es, hay dos cosas realmente: definir el símbolo, que ocurre antes de que se ejecute la primera línea de código; y hacer una asignación a ese símbolo, que ocurre donde la línea está en el flujo paso a paso. Esto se conoce como " var hoist" porque la parte var foo se mueve ("izó") a la parte superior del alcance, pero la parte foo = "f" se deja en su ubicación original. (Ver var mal entendido mal en mi pequeño blog anémico.)

Cuando let y const suceden

let y const son diferentes de var en un par de formas. La forma en que es relevante para la pregunta es que aunque el enlace que definen se crea antes de que se ejecute cualquier código paso a paso, no se puede acceder hasta let se alcance la instrucción let o const .

Así que mientras esto se ejecuta:

display(a); // undefined var a = 0; display(a); // 0

Esto arroja un error:

display(a); // ReferenceError: a is not defined let a = 0; display(a);

Las otras dos formas en que let y const difieren de var , que no son realmente relevantes para la pregunta, son:

  1. var siempre se aplica a todo el contexto de ejecución (en todo el código global, o en todo el código de función en la función donde aparece), pero let y const aplican solo dentro del bloque donde aparecen. Es decir, var tiene un alcance de función (o global), pero let y const tiene un alcance de bloque.

  2. Repetir var a en el mismo contexto es inofensivo, pero si ha let a (o const a ), tener otra o una o una const a o una var a es un error de sintaxis.

Aquí hay un ejemplo que demuestra que let y const surten efecto inmediatamente en su bloque antes de que se ejecute cualquier código dentro de ese bloque, pero no se puede acceder hasta la declaración let o const :

var a = 0; console.log(a); if (true) { console.log(a); // ReferenceError: a is not defined let a = 1; console.log(a); }

Tenga en cuenta que el segundo console.log falla, en lugar de acceder a la a desde fuera del bloque.

Fuera de tema: Evite saturar el objeto global ( window )

El objeto de la window vuelve muy, muy abarrotado de propiedades. Siempre que sea posible, recomiendo encarecidamente que no se agregue al desorden. En su lugar, envuelva sus símbolos en un pequeño paquete y exporte a lo sumo un símbolo al objeto de la window . (Con frecuencia no exporto ningún símbolo al objeto de la window ). Puede usar una función para contener todo su código para contener sus símbolos, y esa función puede ser anónima si lo desea:

(function() { var a = 0; // `a` is NOT a property of `window` now function foo() { alert(a); // Alerts "0", because `foo` can access `a` } })();

En ese ejemplo, definimos una función y la ejecutamos de inmediato (la () al final).

Una función utilizada de esta manera con frecuencia se denomina función de alcance . Las funciones definidas dentro de la función de alcance pueden acceder a las variables definidas en la función de alcance porque se cierran sobre esos datos (ver: Los cierres no son complicados en mi pequeño blog anémico).


<title>Index.html</title> <script> var varDeclaration = true; noVarDeclaration = true; window.hungOnWindow = true; document.hungOnDocument = true; </script> <script src="external.js"></script> /* external.js */ console.info(varDeclaration == true); // could be .log, alert etc // returns false in IE8 console.info(noVarDeclaration == true); // could be .log, alert etc // returns false in IE8 console.info(window.hungOnWindow == true); // could be .log, alert etc // returns true in IE8 console.info(document.hungOnDocument == true); // could be .log, alert etc // returns ??? in IE8 (untested!) *I personally find this more clugy than hanging off window obj

¿Hay un objeto global del que todos los vars están colgados de forma predeterminada? por ejemplo: ''declaración globals.noVar''