2009-08-05 14 views
49

He estado usando JSLint para hacerme sentir mal acerca de mi JavaScript. Es genial, por cierto. Hay un cheque que no entiendo del todo y me gustaría su opinión, por favor.Una var por función en JavaScript?

De jslint.com:

En idiomas con ámbito de bloque, se recomienda generalmente que las variables se declararán en el lugar de su primer uso. Pero como JavaScript no tiene alcance de bloque, es más prudente declarar todas las variables de una función en la parte superior de la función. Se recomienda utilizar una sola sentencia var por función.

¿Cuál es la última frase o comentario en negrita diciendo en realidad? Creo que debería estar declarando múltiples variables como esta?

var foo = 1, bar = 2; 

Y, es la parte "inteligente" sólo un estilo de programación para disuadir a los errores en la línea o hay algo más que eso?

Gracias por su ayuda.

+0

He tenido dos excelentes respuestas de http://stackoverflow.com/users/5445/cms y http://stackoverflow.com/users/51101/breton. Siento que juntos ambos responden esta pregunta. ¿Cómo puedo dar crédito a ambos? :( –

+7

Por cierto, si realmente quieres sentirte mal por tu código, intenta leer el código fuente en JSLINT y averigua cómo funciona. Es perfectamente sencillo y legible, y aún misterioso. Es como descubrir que el universo es un fractal calculado por la ecuación 2 + 2 =? – Breton

+0

¿Alguien no de una herramienta que reformateará automáticamente el código al estilo de una var por función? (pero no minify) – jlarson

Respuesta

71

El problema es que, ya sea que se dé cuenta o no, javascript invisiblemente mueve todas las declaraciones var a la parte superior del alcance de la función.

por lo que si usted tiene una función como esta

var i = 5; 
function testvar() { 
    alert(i); 
    var i=3; 
} 
testvar(); 

la ventana de alerta que contiene indefinido. porque internamente, se ha cambiado a esto:

var i = 5; 
function testvar() { 
    var i; 
    alert(i); 
    i=3; 
} 
testvar(); 

Esto se llama "alzando". La razón por la que crockford defiende tan firmemente que las declaraciones de var van en la parte superior, es que hace que el código se ajuste visiblemente a lo que va a hacer, en lugar de permitir que ocurra un comportamiento invisible e inesperado.

+0

Interesante - nunca lo sabía realmente sobre JS - por supuesto, generalmente defino todas mis variables en la parte superior de todos modos, y rara vez reutilizo un nombre de variable de un bucle/función externa. – gnarf

+0

Esto es interesante, pero no está realmente relacionado con el alcance del bloque. – Triptych

+0

Pero es una respuesta válida a mi pregunta ... –

8

Básicamente en bloques de JavaScript ({ ... }) no introduzca un nuevo ámbito, solo existe el ámbito de función, por lo que no se crea ámbito en ninguna otra instrucción.

Una variable introducida en cualquier lugar de una función es visible en todas partes en la función.

Por ejemplo:

function myFunction(){ 
    var one = 1; 

    if (one){ 
    var two = one + 1; 
    } 

    (function() { 
    var three = one + two; 
    })(); 

    // at this point both variables *one* and *two* are accessible but 
    // the variable *three* was declared in the scope of a inner function 
    // and is not accessible at this point. 
} 

En idiomas con ámbito de bloque, se recomienda declarar las variables en el punto de inicio del consumo, pero desde JavaScript no tiene ámbito de bloque, es mejor declarar toda una las variables de función en la parte superior de la función.

Marque esta article.

+2

No explicas por qué es mejor, sin embargo, se deriva del alcance de la función que es mejor para los vars estar en la cima. Pero has omitido los pasos de razonamiento desde ese hecho hasta tu conclusión. – Breton

+3

Acabo de leer el artículo con el que me vinculaste, y comete el mismo error que Chetan. redeclar una var es un NOOP. Es completamente benigno y no causa ningún problema. Lo que no quiere decir es que restringirse a una sola declaración de var es inútil, pero usted, ni el artículo, en realidad ha hecho un caso convincente para ello. – Breton

+0

@Breton, puede causar problemas porque a menudo es un reflejo de un programador confundido. También puede confundir a otros programadores que hacen lo sensato y poner todos los vars en la parte superior de la función. – Nosredna

4

Sí, esto significa que se declara todas las variables al comienzo de la función. Si desea hacerlo en una línea o en varias líneas es una cuestión de elección.

El motivo se explica en el párrafo que ha mencionado. Las variables Javascript solo tienen alcance de nivel de función. Si declara la misma variable dentro de un bloque if/while/for, se sobrescribirá con el nuevo valor ya que el bloque no tiene un nuevo alcance. Esto es diferente de idiomas como Java. Para evitar tales sorpresas, declare todas las variables que va a usar en la función al comienzo de la función para que no "redeclare" accidentalmente y nada.

+0

No creo que redeclarar una variable sea el problema. Eso no arroja un error como en C (¿o java?). De hecho, no hace nada. – Breton

+0

Lo siento, debo haber sido más claro. Lo que quise decir fue declarar el mismo nombre de variable dentro de un bloque, lo cual está permitido en Java. Esta nueva variable vive solo dentro del bloque. –

+0

Ah sí, supongo que eso sería un problema si estuvieras acostumbrado a un lenguaje con alcance de bloque. – Breton

6

La falta de ámbito de bloque explica el código de abajo:

var a = 1; 
if (something) { 
    var a = 2; 
} 

alert(a); // Alerts "2" 

En la mayoría de estilo C (como en la sintaxis) idiomas, la definición var a = 2 definiría 'a' sólo para el ámbito del bloque if. Usar una sola instrucción var en la parte superior de la función ayuda a evitar esta peculiaridad de Javascript, que no siempre es tan obvio como el anterior, y sería inesperado para los programadores C/C#/Java.

Cuestiones relacionadas