2011-07-31 32 views
33

En w3schools allí se escribe:Declaración de variables sin palabra clave var

Si se declara una variable, sin necesidad de utilizar "var", la variable siempre se vuelve global.

¿Es útil para declarar variables globales dentro de la función? Me puedo imaginar para declarar algunas variables globales en algún controlador de eventos, pero ¿para qué sirve? Mejor uso de RAM

Respuesta

69

Las variables globales son una mala idea. Solo deben usarse cuando sea absolutamente necesario. No hay beneficio de RAM ni nada de eso.

Lo que está hablando w3schools es The Horror of Implicit Globals. Considere esta función:

function foo() { 
    var x; 

    x = 5; 
    y = 6; 
    return x + y; 
} 

Cuando se ejecuta esta función, de repente, de la nada, tiene una variable global llamada y. Esto se debe a que la función asigna al y, pero y no está declarado en ningún lado. A través de la mecánica de la cadena de ámbito en JavaScript, esto termina siendo una asignación implícita a una propiedad en el objeto global (al que puede acceder como window en los navegadores). Por ejemplo, en el supuesto y no se ha declarado en cualquier ámbito que contiene, es exactamente lo mismo que esto:

function foo() { 
    var x; 

    x = 5; 
    window.y = 6; 
    return x + window.y; 
} 

El objeto global contiene todas las variables globales (actualización que utiliza a, ES6 agregó una forma de declarar variables globales que no terminan en window, ver la nota a continuación), ambos definidos explícita e implícitamente. Puede imaginarse que hay un lote de variables globales creadas por el código de las personas por accidente.

El objeto global ya está muy, muy desordenado. A menos que esté escribiendo una biblioteca o una página que tenga que usar varios archivos de script, no hay razón para complicar aún más el objeto global. Apenas define a sí mismo una función de alcance agradable y poner los símbolos en ella:

(function() { 
    var your, symbols, here, if_they_need, to_be_shared, amongst_functions; 

    function doSomething() { 
    } 

    function doSomethingElse() { 
    } 
})(); 

Y si lo hace, es posible que desee invocar la nueva strict mode de JavaScript, añadido en el quinto especificación de edición:

(function() { 
    "use strict"; 
    var your, symbols, here, if_they_need, to_be_shared, amongst_functions; 

    function doSomething() { 
    } 

    function doSomethingElse() { 
    } 
})(); 

... que tiene la ventaja de (amongst other things) haciendo que la creación implícita de la función foo de una variable global sea ReferenceError.


Actualización: ES6 y globales: A partir de ES6, una nueva especie de la que se creó mundial no es una propiedad del objeto global: Globals crean a través de let, const, o class. Esas palabras clave nuevas, cuando se utilizan en el ámbito global, crean globales que no se convierten en propiedades del objeto global y, por lo tanto, no se puede acceder a través de window en los navegadores.

+0

-1 debido a su primera oración. Las variables globales son una mala idea? ** ¿Siempre? ** No, a veces son una muy buena idea. Depende de para qué los uses. Odio declaraciones universales como esta que no son verdaderas; no pertenecen a la programación. – Andrew

+1

@Andrew: Podría darme crédito por la * segunda * oración, entonces. ¿Seguramente el resto de la respuesta compensa tus problemas con la primera oración? –

+0

Su segunda oración complementa la primera, entonces no. Las variables globales no son una mala idea, a menudo son una mala idea.No solo deben usarse cuando sea absolutamente necesario, sino que deben usarse siempre que sea apropiado para que la memoria sea accesible globalmente. Y lo siento, no, "use strict" no es una solución típicamente ideal para JavaScript, a menos que lo esté usando globalmente para algo más oficial como TypeScript; de lo contrario, es un truco que debes mantener constantemente (colocándolo en todas partes) para asegurarte de que no escribes un código incorrecto, contradictorio. – Andrew

3

El único uso de las variables globales es si necesita acceder a ellas globalmente.En ese caso, debe declararlos utilizando la palabra clave var fuera de las funciones, para dejar en claro que realmente desea crear variables globales, y no se olvidó del var al intentar declarar una variable local.

Por lo general, debe intentar determinar el alcance de su código para que necesite lo menos posible en el ámbito global. Cuantas más variables globales utilice en su secuencia de comandos, menor será la posibilidad de que pueda usarla junto con otra secuencia de comandos.

Normalmente, las variables en una función deben ser locales, de modo que desaparezcan cuando salga de la función.

+0

Es extraño que javascript permita construcciones que no son útiles, pero que solo pueden causar problemas cuando escribimos mal. – xralf

+1

@xralf: todos los lenguajes permiten construcciones que pueden ser mal utilizadas. 'while (true);' viene a la mente. –

2

A veces es útil para crear nuevas propiedades accesibles a nivel mundial dentro de funciones a las que luego se puede acceder fácilmente al hacer referencia al objeto de ventana (todas las propiedades declaradas globalmente se adjuntan al objeto ventana).

Sin embargo, como generalmente se declara que cualquier cosa es accesible globalmente, puede ocasionar problemas más adelante porque esas propiedades se pueden sobrescribir fácilmente, etc. Es mucho mejor simplemente pasar valores a funciones como argumentos y recuperar sus resultados.

1

El problema principal es que alguien más ya puede estar usando un global con el mismo nombre.

Luego, cuando cambie el valor global, sobrescribirá su valor.

Más tarde, cuando se utilice a continuación el mundo, habrá cambiado misteriosamente.

+2

"Alguien más", podrías ser tú pero has olvidado que ya has usado ese nombre en otro lugar. – QuentinUK

+0

O incluso que tiene un elemento en su página que utiliza ese 'id', ya que todos ellos son lanzados en el objeto' window' en casi todos los navegadores. (Creo que Firefox es el único resistido.) –

16

efectos secundarios al olvidar var

Hay una ligera diferencia entre variables globales implícitas y explícitamente definidos queridos. La diferencia está en la capacidad de remover la definición de estas variables utilizando el operador delete:

• Globals creados con var (los creados en el programa fuera de cualquier función) no se pueden borrar.

• Las variables globales implícitas creadas sin var (independientemente de si se han creado dentro de las funciones) pueden ser borradas.

Esto muestra que los globales implícitos técnicamente no son variables reales, pero son propiedades del objeto global. Las propiedades se pueden eliminar con el operador delete mientras que las variables pueden no:

// define three globals 
var global_var = 1; 
global_novar = 2; // antipattern 
(function() { 
    global_fromfunc = 3; // antipattern 
}()); 
// attempt to delete 
delete global_var; // false 
delete global_novar; // true 
delete global_fromfunc; // true 
// test the deletion 
typeof global_var; // "number" 
typeof global_novar; // "undefined" 
typeof global_fromfunc; // "undefined" 

En modo estricto ES5, las asignaciones a las variables no declaradas (tales como los dos antipatterns en el fragmento anterior) generará un error.

Patrones de JavaScript, por Stoyan Stefanov (O'Reilly). Copyright 2010 Yahoo !, Inc., 9780596806750.

+0

ligera modificación necesaria en // tipo de resultado variable Cuando intenté ejecutar la declaración de variables arriba en el compilador w3school me puse en alerta (typeof global_var); // número de alerta (typeof global_novar); // alerta de número (typeof global_fromfunc); // undefined –

+0

¡Explicación útil! Gracias :) –

Cuestiones relacionadas