var

Resumen

La sentencia var declara una variable, opcionalmente inicializ谩ndola con un valor.

Sintaxis

var nombreDeVariable1 [= valor1] [, nombreDeVariable2 [= valor2] ... [, nombreDeVariableN [=valorN]]]; 
nombreDeVariableN
Representa el nombre que el programador da a la variable. Puede ser cualquier identificador legal.
valorN
Valor inicial de la variable. Puede ser cualquier expresi贸n legal. El valor predeterminado es undefined (en espa帽ol, indefinida).

Descripci贸n

Las  declaraciones de variables, donde sea que ocurran, son procesadas antes de que cualquier otro c贸digo sea ejecutado. El 谩mbito de una variable declarada con la palabra reservada var es su contexto de ejecuci贸n en curso, que puede ser la funci贸n que la contiene o, para las variables declaradas afuera de cualquier funci贸n, un 谩mbito global. Si re-declaras una variable Javascript, esta no perder谩 su valor.

Asignar un valor a una variable no declarada implica crearla como variable global (se convierte en una propiedad del objeto global) cuando la asignaci贸n es ejecutada. Las diferencias entre una variable declarada y otra sin declarar son:

1. Las variables declaradas se limitan al contexto de ejecuci贸n en el cual son declaradas. Las variables no declaradas siempre son globales.

function x() {
  y = 1;   // Lanza un error de tipo "ReferenceError" en modo estricto ('use strict')
  var z = 2;
}

x();

console.log(y); // Imprime "1" 
console.log(z); // Lanza un error de tipo "ReferenceError": z no est谩 definida afuera de x

2. Las variables declaradas son creadas antes de ejecutar cualquier otro c贸digo. Las variables sin declarar no existen hasta que el c贸digo que las asigna es ejecutado.

console.log(a);                // Lanza un error de tipo "ReferenceError".
console.log('trabajando...'); // Nunca se ejecuta.
var a;
console.log(a);                // Imprime "undefined" o "" dependiendo del navegador.
console.log('trabajando...'); // Imprime "trabajando...".

3. Las variables declaradas son una propiedad no-configurable de su contexto de ejecuci贸n (de funci贸n o global). Las variables sin declarar son configurables (p. ej. pueden borrarse).

var a = 1;
b = 2;

delete this.a; // Lanza un error de tipo "ReferenceError" en modo estricto ('use strict'), de lo contrario falla silenciosamente.
delete this.b;

console.log(a, b); // Lanza un error de tipo "ReferenceError". 
// La propiedad 'b' se elimin贸 y ya no existe.

Debido a esas tres diferencias, fallar al declarar variables muy probablemente llevar谩 a resultados inesperados. Por tanto se recomienda siempre declarar las variables, sin importar si est谩n en una funci贸n o un 谩mbito global. Y en el modo estricto (strict mode) de ECMAScript 5, asignar valor a una variable sin declarar lanzar谩 un error.

Elevaci贸n de variables

Como la declaraci贸n de variables (y todas las declaraciones en general) se procesa antes de ejecutar cualquier c贸digo, declarar una variable en cualquier parte del c贸digo es equivalente a declararla al inicio del mismo. Esto tambi茅n significa que una variable puede parecer usarse antes de ser declarada. Este comportamiento es llamado hoisting (del ingl茅s "elevaci贸n"), ya que la declaraci贸n de una variable parecer haber sido movida a la cima de la funci贸n o c贸digo global.

bla = 2;
var bla;
// ...

// Es entendido implicitamente como:

var bla;
bla = 2;

Por esa raz贸n, se recomienda siempre declarar variables al inicio de su 谩mbito (la cima del c贸digo global y la cima del c贸digo de funci贸n) para que sea claro cu谩les variables pertenecen al 谩mbito de funci贸n (local) y cu谩les son resueltas en la cadena de 谩mbito.

Es importante se帽alar que la elevaci贸n afectar谩 la declaraci贸n de variables, pero no su inicializaci贸n. El valor ser谩 asignado precisamente cuando la sentencia de asignaci贸n sea alcanzada:

function haz_algo() {
  console.log(bar); // undefined (valor indefinido)
  var bar = 111;
  console.log(bar); // 111
}

// Se entiende impl铆citamente como: 
function haz_algo() {
  var bar;
  console.log(bar); // undefined (valor indefinido)
  bar = 111;
  console.log(bar); // 111
}

 

Ejemplos

Declarando e inicializando dos variables

var a = 0, b = 0;

Asignando dos variables con un solo valor de cadena

var a = 'A';
var b = a;

// Equivalente a:

var a, b = a = 'A';

S茅 consciente del orden:

var x = y, y = 'A';
console.log(x + y); // Imprimir谩 "undefinedA"

Aqu铆, 'x' & 'y' son declaradas antes de ejecutarse cualquier c贸digo, y la asignaci贸n ocurre despu茅s. Al momento de evaluar "x = y", 'y' existe as铆 que ning煤n error "ReferenceError" es lanzado y su valor es 'undefined', de modo que 'x' tambi茅n tiene asignada el valor 'undefined'. Despu茅s, a 'y' se le asigna el valor 'A'. Consecuentemente, luego de la primera l铆nea, 'x' es exactamente igual a 'undefined' & 'y' es igual a 'A', de ah铆 el resultado.

Initializaci贸n de muchas variables

var x = 0;

function f() {
  var x = y = 1; // 'x' es declarada localmente, 隆'y' no lo es!
}
f();

console.log(x, y); // Lanza un error de tipo "ReferenceError" en modo estricto ('y' no est谩 definida). De lo contrario se imprimir铆a "0, 1".
// En modo no-estricto:
// 'x' es la variable global como se esperar铆a
// 'y' sin embargo, se sale de la funci贸n

Globales impl铆citas y 谩mbito externo a una funci贸n

Las variables que parecen ser globales impl铆citas pueden ser referencias a variables en un 谩mbito externo a  la funci贸n:

var x = 0;  // 'x' es declarada globalmente, luego se le asigna el valor 0.

console.log(typeof z); // Imprime "undefined", pues 'z' a煤n no existe.

function a() { // Cuando 'a()' es invocada,
  var y = 2;   // 'y' es declarada localmente en la function 'a()', despu茅s se le asigna el valor 2.

  console.log(x, y);   // Imprime "0, 2".

  function b() {       // Cuando 'b()' es invocada,
    x = 3;  // Asigna el valor 3 a la global 'x' ya existente, no crea una nueva variable global.
    y = 4;  // Asigna 4 a la externa existente 'y', no crea una nueva variable global.
    z = 5;  // Crea una nueva variable global 'z' y le asigna un valor de 5. 
  }         // (Lanza un error de tipo "ReferenceError" en modo estricto.)

  b();     // Invocar 'b()' crea 'z' como variable global.
  console.log(x, y, z);  // Imprime "3, 4, 5".
}

a();                   // Invocar 'a()' tambi茅n llama a 'b()'.
console.log(x, z);     // Imprime "3, 5", porque 'z' ya es una global.
console.log(typeof y); // Imprime 'undefined' porque 'y' es local en la funci贸n 'a()'