2012-04-18 16 views
10

Estoy seguro de que he leído un debate sobre SO sobre esto pero no puedo encontrarlo. Simplemente, ¿hay contras para declarar un incremento de bucle for dentro de la declaración del bucle? ¿Cuál es la diferencia entre esto:Declarar var dentro de Javascript para la declaración de bucle

function foo() { 
    for (var i=0; i<7; i++) { 
     // code 
    } 
} 

... y esto:

function foo() { 
    var i; 
    for (i=0; i<7; i++) { 
     // code 
    } 
} 

Desde JS tiene ámbito de la función, o bien debe estar bien, ¿verdad? ¿Hay casos límite en los que el primer enfoque causaría problemas?

Si son idénticos, ¿por qué Crockford/JSLint todo, "No way dawg," al respecto?

+2

Posible duplicado de [las variables de JavaScript declaran bucle externo o interno?] (Http://stackoverflow.com/questions/3684923/javascript-variables-declare-outside-or-inside-loop) –

Respuesta

12

Estos son exactamente lo mismo. Todas las variables locales en javascript tienen un alcance de función, lo que significa que están activas para toda la función en la que están declaradas. Esto a menudo es contra intuitivo al principio, ya que la mayoría de las llaves se ajustan al ciclo en el que están declaradas.

Una parte de los desarrolladores de Javascript prefieren mucho la segunda forma. La razón es que, dado que todas las variables tienen alcance de función, debe declararlas en el nivel de función para hacer explícito el tiempo de vida incluso para aquellos que no están familiarizados con Javascript. Esto es sólo un estilo sin embargo y de ninguna manera una regla dura

EDITAR

Tenga en cuenta que con la introducción de ES6 let, ahora se puede utilizar deje dentro de su bucle de verdad bloque de ámbito de variables more details

for(let i = 1; i <= 5; i++) { 
    setTimeout(function(){ 
     console.log('Value of i : ' + i); 
    },100); 
} 
+0

También hay 'let' que es similar a' var' ya que también da un alcance local, pero difiere en que recibe el alcance del bloque. No es accesible fuera de un 'for' /' if'/'while' etc. – 4castle

0

Esas son exactamente lo mismo.

+0

No es una respuesta muy útil; la pregunta es, dado que son funcionalmente equivalentes, ¿por qué la regla en JSLint? JSLint es asombrosamente exigente con una amplia variedad de cosas, cuya importancia para usted puede variar ampliamente, pero hay un método para su locura. –

+0

JSLint no significa nada. – Rob

+1

Jaja, significa algo ... tal vez no mucho, pero para un novato como yo ayuda a establecer buenos hábitos. –

7

El problema con declarar con var en el encabezado de bucle es que es engañoso. Se ve como que está declarando una variable cuyo alcance se limita al bucle for, cuando en realidad existe en todas partes dentro de la función - incluyendo antes de la declaración:

var i = 1; 
function foo() { 
    console.log(i);      // 'undefined' 
    for (var i=1; i<100; ++i) { 
    } 
} 

A pesar de que la llamada console.log ocurre antes la declaración del i local, todavía está en el alcance porque está dentro de la misma función. Por lo tanto, el i local, que aún no tiene ningún valor asignado, pasa a log. Esto puede ser sorprendente; ciertamente no es obvio para cualquiera que no esté familiarizado con las reglas de alcance de Javascript.

A partir de ECMAScript 2015, existe una forma mejor de declarar las variables: let. Las variables declaradas con let son locales al bloque que las contiene, no a toda la función. Por lo que esta versión del código anterior imprimir 1 según lo previsto:

let i=1; // could use var here; no practical difference at outermost scope 
function foo() { 
    console.log(i);    // 1 
    for (let i=1; i<100; ++i) { 
    } 
} 

así que las mejores prácticas en Javascript moderna es para declarar variables con let en lugar de var. Sin embargo, si está atrapado con una implementación anterior a ECMAScript 2015, es un poco menos confuso declarar todas las variables en la parte superior de la función, en lugar de esperar hasta el primer uso.

+0

Por lo tanto, mientras esté familiarizado con el manejo del alcance de Js, entonces todo está bien. –

+1

es por eso que la gente debe dejar de usar 'var' –

+0

Gracias por el recordatorio, @SartherisStormhammer. Actualizado para abordar la disponibilidad de 'let' en el lenguaje moderno. –

1

No hay diferencia, pero yo prefiero la segunda manera (por Crockford) porque demuestra explícitamente que la variable disponible fuera del bucle for:

function() { 
    for(var i=0; i<7; i++) { 
     // code 
    } 

    // i is still in scope here and has value 7 
} 
0

El bloque de código dos son idénticos. La primera instrucción del bucle for se ejecuta antes de que se inicie el bucle for, el bucle se ejecuta mientras que la segunda instrucción es verdadera y la tercera instrucción se ejecuta cada vez que el bucle se repite una vez.

Esto significa que

for(var i = 0; i < 8; i++) { 
    //some Code 
} 

es idéntica a

var i = 0; 
for(;i < 8;) { 
    //some Code 
    i++; 
} 

(El punto y coma siguiendo el ( es para indicar al ordenador que i < 8 es en realidad la segunda declaración, no es la primera).

Cuestiones relacionadas