¿Cuál es la diferencia entre una variable global y una ‘window.variable’ en JavaScript?

4 minutos de lectura

avatar de usuario
Derick Bailey

estoy leyendo el Backbone.js documentos y veo mucho código que asigna atributos a los ventana objeto:

window.something = "whatever";

¿Cuál es la diferencia entre llamar a este código y simplemente asignar la variable y crear una variable global, como esta:

something = "whatever";

Supongo que hay algún tipo de diferencia de alcance y/o diferencia de propiedad del objeto (ventana ser el propietario vs. no), pero estoy interesado en el detalle entre los dos y por qué usaría ventana vs. no usarlo.

  • Esto no está realmente relacionado con su caso particular, pero recuerde que Javascript no tener para ejecutarse en un navegador, por lo que la ventana no tener por definir

    – Andrei Barsan

    20 mayo 2013 a las 14:44

avatar de usuario
Raynos

Ninguna diferencia. Ambos tienen el mismo efecto (En el navegador, donde window es el contexto mundial1).

  • window.foo = "bar" establece la propiedad foo en window.
  • foo = "bar" indica cualquiera un error o intencionalmente global.

Dado que tengo que verificar dos veces si es un error tipográfico o no, personalmente lo encuentro más legible establecer window.foo directamente.

Además, en modo estricto ES5, foo = "bar" es una cesión ilegal porque foo no se declara y arrojará un Error.

Editar:

Como se indica en los comentarios, foo = "bar" buscará hasta el final de la cadena de alcance de la variable foo y reasignarlo con "bar" si se encuentra. Si no se encuentra, creará una nueva variable global.

También con window.foo = "bar" solo está asignando una propiedad a un objeto, que se puede eliminar usando delete window.foo.

En ES5 modo estricto es inválido a delete una variable.


1 En otros entornos, como node.js y Web Workers, puede haber otro nombre para el objeto global y window puede que no exista en absoluto. Usos de Node.js global y Web Workers usan self.

  • Aparte, puede eliminar window.foo pero no un foo global definido con var.

    – Kennebec

    14 de junio de 2011 a las 19:57

  • Hay una diferencia. window.foo = bar; establece foo en el objeto de la ventana. foo = bar; busca en la cadena de alcance hasta que encuentra fooque puede terminar siendo el objeto global, pero no siempre.

    – David

    14/06/2011 a las 20:00

  • @kennebec Creo que eso es específico del navegador.

    – Raynos

    14 de junio de 2011 a las 20:01

  • @Raynos: la diferencia de poder eliminar no es realmente específica del navegador. De acuerdo con la especificación ECMAScript y asumiendo window es el objeto global, el comportamiento que describe @kennebec es correcto. Sin embargo, las versiones anteriores de IE no se ajustan.

    – Tim Abajo

    14 de junio de 2011 a las 23:12

  • @TimDown No se supone que sea específico del navegador, pero lo es. Sin embargo, estoy de acuerdo en que la especificación ES dice que puede eliminar propiedades.

    – Raynos

    15 de junio de 2011 a las 14:04

avatar de usuario
gion_13

Ambos hacen algo parecido. Pero al acceder a un ventana propiedad, sabe con certeza que está accediendo a una variable global sin importar en qué ámbito se encuentre.

Por ejemplo:

globalVar = "smth";
function(){
    var globalVar = 2;
    alert(globalVar); // Points to the current scope globalVar
    alert(window.globalVar); // Points to the original globalVar
}

En otras palabras, si desea trabajar con globales, es algo más seguro acceder a ellos a través de su contenedor: window.variable

avatar de usuario
scottkoon

La clave, como aludió Raynos, es que se establece explícitamente en el ventana objeto. En el navegador, el objeto global es el mismo que el ventana objeto pero en otros entornos (p. ej., Node.js, o tal vez ejecutándose en una vista web de algún tipo en un dispositivo móvil), puede que no.

la diferencia es que window.foo = bar; no puede ser interceptado por una refactorización hecha más tarde. Usando foo = bar; significa que si, en una fecha posterior, el código se traslada a un cierre donde var foo ha sido definido, ya no lo establecerá en el objeto global.

Agregando un punto más:

Si refieres un variable no declarada directamente (sin usar – ventana o tipo de) entonces obtendrá una variable no definida error.

Ejemplos:

// var unDecVariable

if (unDecVariable != null) // Error: unDecVariable is not defined
{
    // do something
}

if (window.unDecVariable != null) // No Error
{
    // do something
}

if (typeof unDecVariable != 'undefined' && unDecVariable != null) // Alternative way
{
    // do something
}

¿Ha sido útil esta solución?