NOTA : Esta pregunta se hizo desde el punto de vista de ECMAScript versión 3 o 5. Las respuestas podrían quedar desactualizadas con la introducción de nuevas características en el lanzamiento de ECMAScript 6.
¿Cuál es exactamente la función de la var
palabra clave en JavaScript y cuál es la diferencia entre
var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;
y
someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;
?
¿Cuándo usaría alguno de ellos y por qué / qué hace?
Respuestas:
Si estás en el ámbito global, entonces no hay mucha diferencia. Lea la respuesta de Kangax para una explicación.
Si está en una función
var
, creará una variable local, "no var" buscará la cadena de alcance hasta que encuentre la variable o llegue al alcance global (en ese momento la creará):Si no está haciendo una tarea, debe usar
var
:fuente
Hay una diferencia .
var x = 1
declara variablex
en el alcance actual (también conocido como contexto de ejecución). Si la declaración aparece en una función, se declara una variable local; si está en alcance global, se declara una variable global.x = 1
, por otro lado, es simplemente una asignación de propiedad. Primero intenta resolverx
contra la cadena de alcance. Si lo encuentra en algún lugar de esa cadena de alcance, realiza la asignación; si no encuentrax
, solo entonces crea unax
propiedad en un objeto global (que es un objeto de nivel superior en una cadena de alcance).Ahora, observe que no declara una variable global, crea una propiedad global.
La diferencia entre los dos es sutil y puede ser confusa a menos que comprenda que las declaraciones de variables también crean propiedades (solo en un Objeto variable) y que cada propiedad en Javascript (bueno, ECMAScript) tiene ciertos indicadores que describen sus propiedades: ReadOnly, DontEnum y No borrar
Como la declaración variable crea una propiedad con el indicador DontDelete, la diferencia entre
var x = 1
yx = 1
(cuando se ejecuta en alcance global) es que la primera, la declaración variable, crea la propiedad DontDelete'able, y la segunda no. Como consecuencia, la propiedad creada a través de esta asignación implícita se puede eliminar del objeto global, y la primera, la creada mediante declaración de variable, no se puede eliminar.Pero esto es solo teoría, por supuesto, y en la práctica hay aún más diferencias entre los dos , debido a varios errores en las implementaciones (como las de IE).
Espero que todo tenga sentido :)
[Actualización 2010/12/16]
En ES5 (ECMAScript 5; recientemente estandarizado, 5ta edición del lenguaje) hay un llamado "modo estricto" - un modo de lenguaje opcional, que cambia ligeramente el comportamiento de las tareas no declaradas. En modo estricto, la asignación a un identificador no declarado es un Error de referencia . La razón de esto fue detectar asignaciones accidentales, evitando la creación de propiedades globales no deseadas. Algunos de los navegadores más nuevos ya han comenzado a admitir el modo estricto. Ver, por ejemplo, mi tabla compat .
fuente
delete
una variable declarada var con algúneval
truco. Si recuerdo el truco exacto que publicaré aquí.var someObject = {}
ysomeObject.someProperty = 5
? ¿SesomeProperty
volvería global, mientras que el objeto del que es propiedad sigue siendo local?false
) , puede leer sobre esto con respecto aObject.defineProperty
yObject.getOwnPropertyDescriptor
Decir que es la diferencia entre " local y global " no es del todo exacto.
Sería mejor pensar en ello como la diferencia entre " local y más cercano ". El más cercano seguramente puede ser global, pero ese no siempre será el caso.
fuente
outer
donde definevar global = false;
?var global = local;
en cuyo caso el alcance cercano de local sería el alcance externo "local" que se está definiendo activamente. Aunque se vuelve extraño si cambiara esa misma líneavar global = global
en cuyo caso el alcance más cercano al buscar el valorglobal
estaría arriba en el alcance de la ventana global.Cuando Javascript se ejecuta en un navegador, todo su código está rodeado por una instrucción with, así:
Más información sobre
with
- MDNComo
var
declara una variable en el alcance actual , no hay diferencia entre declararvar
dentro de la ventana y no declararla en absoluto.La diferencia viene cuando no estás directamente dentro de la ventana, por ejemplo, dentro de una función o dentro de un bloque.
Utilizando
var
permite ocultar variables externas que tienen el mismo nombre. De esta manera, puede simular una variable "privada", pero ese es otro tema.Una regla general es usar siempre
var
, porque de lo contrario corre el riesgo de introducir errores sutiles.EDITAR: Después de las críticas que recibí, me gustaría enfatizar lo siguiente:
var
declara una variable en el alcance actualwindow
var
declara implícitamentevar
en el ámbito global (ventana)var
es lo mismo que omitirla.var
no es lo mismo declarar una variable sinvar
var
explícitamente porque es una buena prácticafuente
let
en ES6.Utilice siempre la
var
palabra clave para declarar variables. ¿Por qué? Una buena práctica de codificación debería ser una razón suficiente en sí misma, pero omitirla significa que se declara en el ámbito global (una variable como esta se denomina global "implícita"). Douglas Crockford recomienda nunca usar globales implícitos , y de acuerdo con las Pautas de codificación JavaScript de Apple :fuente
good coding practice
siempre es una razón suficiente si es una práctica recomendada, que es y por varios autores de Javascript.Aquí hay un buen ejemplo de cómo puede quedar atrapado al no declarar variables locales con
var
:(
i
se restablece en cada iteración del bucle, ya que no se declara localmente en elfor
bucle sino globalmente) lo que finalmente da como resultado un bucle infinitofuente
Yo diría que es mejor usar
var
en la mayoría de las situaciones.Las variables locales son siempre más rápidas que las variables de alcance global.
Si no usas
var
para declarar una variable, la variable estará en el ámbito global.Para obtener más información, puede buscar "JavaScript de cadena de alcance" en Google.
fuente
¡No lo uses
var
!var
era la forma anterior a ES6 para declarar una variable. Ahora estamos en el futuro , y deberías estar codificando como tal.Uso
const
ylet
const
debe usarse para el 95% de los casos. Hace que la referencia variable no pueda cambiar, por lo que las propiedades de la matriz, el objeto y el nodo DOM pueden cambiar y probablemente deberían serloconst
.let
debe usarse para cualquier variable que espera ser reasignada. Esto incluye dentro de un bucle for. Si alguna vez escribevarName =
más allá de la inicialización, uselet
.Ambos tienen un alcance de nivel de bloque, como se esperaba en la mayoría de los otros idiomas.
fuente
otra diferencia eg
mientras
fuente
var
?var a
se eleva a la parte superior del alcance y se establece en nulo, lo que declara pero no inicializa la variable, luego, en la asignación, tiene una referencia a una variable nula indefinida que se evalúa como falsa y establece la asignación en[]
. En este último, tiene una asignación a la propiedada
de la propiedada
. Puede asignar a una propiedad que no existe, creándola en la asignación, pero no puede leer de una propiedad que no existe sin que leReferenceError
arrojen.Usar
var
siempre es una buena idea para evitar que las variables desordenen el alcance global y que las variables entren en conflicto entre sí, causando una sobrescritura no deseada.fuente
Sin
var
- variable global.Se recomienda encarecidamente SIEMPRE usar la
var
declaración, porque la variable global init en el contexto local es malvada. Pero, si necesita este truco sucio, debe escribir un comentario al comienzo de la página:fuente
Este es un código de ejemplo que he escrito para que entiendas este concepto:
fuente
@ Chris S dio un buen ejemplo mostrando la diferencia práctica (y el peligro) entre
var
y novar
. Aquí hay otro, considero que este es particularmente peligroso porque la diferencia solo es visible en un entorno asincrónico, por lo que puede pasar fácilmente durante las pruebas.Como era de esperar, las siguientes salidas de fragmentos
["text"]
:Lo mismo ocurre con el siguiente fragmento (tenga en cuenta lo que falta
let
antesarray
):Ejecutar la manipulación de datos de forma asincrónica todavía produce el mismo resultado con un solo ejecutor:
Pero se comporta de manera diferente con múltiples:
Usando let sin embargo:
fuente
Como alguien que intenta aprender esto, así es como lo veo. Los ejemplos anteriores fueron quizás un poco demasiado complicados para un principiante.
Si ejecuta este código:
La salida se leerá como: falso, falso, verdadero, verdadero
Debido a que ve las variables en la función como separadas de las que están fuera de ella, de ahí el término variable local y esto se debió a que usamos var en la asignación. Si quitas la var en la función, ahora se lee así:
La salida es falsa, falsa, falsa, falsa
Esto se debe a que, en lugar de crear una nueva variable en el ámbito o función local, simplemente usa las variables globales y las reasigna a falso.
fuente
Veo que la gente se confunde al declarar variables con o sin var y dentro o fuera de la función. Aquí hay un ejemplo profundo que lo guiará a través de estos pasos:
Vea el script a continuación en acción aquí en jsfiddle
fuente
Dentro de un código, si usa una variable sin usar var, entonces lo que sucede es que var var_name se coloca automáticamente en el ámbito global, por ejemplo:
fuente
Además del problema de los alcances, algunas personas también mencionan el izado , pero nadie dio un ejemplo. Aquí hay uno para el alcance global:
fuente
Sin usar "var", las variables solo pueden definirse cuando se establece un valor. Por ejemplo:
no puede funcionar en alcance global ni en ningún otro alcance . Debe tener un valor como:
Por otro lado, puede definir un valor variable;
Su valor es
undefined
(Su valor no esnull
y no es igual anull
interesante).fuente
my_var;
es en realidad una declaración de expresión válida.my_var;
Es una declaración de expresión válida ./my_var;
Sería una declaración inválida. Pero como dije, esto es casuística gramatical, me disculpo, mi comentario en realidad no era apropiado.Debe usar la palabra clave var a menos que tenga la intención de tener la variable asociada al objeto de ventana en el navegador. Aquí hay un enlace que explica el alcance y la diferencia entre el alcance global y el alcance local con y sin la palabra clave var.
Cuando las variables se definen sin el uso de la palabra clave var, lo que parece es una simple operación de "asignación".
Cuando el valor se asigna a una variable en javascript, el intérprete primero intenta encontrar la "declaración de variable" en el mismo contexto / alcance que el de la asignación. Cuando el intérprete se ejecuta
dummyVariable = 20
, busca la declaración de dummyVariable al comienzo de la función. (Dado que todas las declaraciones de variables se mueven al comienzo del contexto por el intérprete de JavaScript y esto se denomina elevación)También es posible que desee ver la elevación en javascript
fuente