2012-01-05 20 views
10

Estoy profundamente confundido por el comportamiento de JavaScript o la consola de Chrome. ¿Puede alguien ayudarme a entender?La consola de JavaScript imprime el valor asignado de la variable antes de que se le haya asignado?

Básicamente tengo el siguiente código JavaScript, no anidado dentro de cualquier función o de otro ámbito:

var initial_array = []; 

function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 

function copyToNewArray() { 
    var copied_array = []; 

    console.log("COPIED 1", copied_array); 

    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 

    console.log("COPIED 2", copied_array); 
} 

initialiseArray(); 
copyToNewArray(); 

yo esperaría COPIED 1 para imprimir [] - como la variable no se ha asignado todavía - pero en su lugar se imprime [2, 9, 8, 6, 0, 2, 1] - es decir, el valor después de que se ha asignado.

¿Por qué?

Por cierto, si reemplaza las líneas 8-11 con initial_array = copied_array, entonces RESULTS 1 de hecho se imprime como []. ¿Tiene algo que ver con usar .push?

+0

Interesante. ¿Esto parece abordar el mismo problema? [link] (http://zef.me/2843/javascript-the-scope-pitfall) – j08691

+4

pregunta similar: http://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about- evaluación de matrices – diEcho

Respuesta

8

Pruebe la depuración de la cuestión en el depurador de scripts Chrome.Ponga un punto de interrupción en la línea:

for (var i = 0; i < initial_array.length; i++) { 

y verá el comportamiento que desee.

El problema que tiene es que está asumiendo incorrectamente que el depurador de Chrome 'imprime' el valor inmediatamente cuando de hecho lo hace console.log de forma asincrónica. Dado que las matrices se pasan por referencia en el back-end cuando en realidad va a imprimir el valor, ahora es el que está viendo.

+0

Una buena recomendación para el depurador de scripts Chrome, estaba intentando con depurador Webstorm sin mucho éxito. – Osy

+0

Buena respuesta ... LAME logger :( – Nicole

0
var initial_array = []; 
function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 
function copyToNewArray() { 
    var copied_array = []; 
    console.log("COPIED 1", copied_array); 
    alert(copied_array.length); 
    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 
    console.log("COPIED 2", copied_array); 
} 
initialiseArray(); 
copyToNewArray(); 

Al agregar la línea alert(copied_array.length); se mostrarán los resultados correctos.

Lo que ocurre es que el registro no está sincronizado con la ejecución de javascript. Cuando el registro se imprime, los valores ya han cambiado.

1

Es la forma en que las matrices se muestran en la consola de Chrome, y eso es por referencia. Si desea obtener resultados precisos, convertir a una cadena:

var initial_array = []; 

function initialiseArray() { 
    initial_array = [2, 9, 8, 6, 0, 2, 1]; 
} 

function copyToNewArray() { 
    var copied_array = []; 

    console.log("COPIED 1", copied_array.toString()); 

    for (var i = 0; i < initial_array.length; i++) { 
     var copy = initial_array[i]; 
     copied_array.push(copy); 
    } 

    console.log("COPIED 2", copied_array.toString()); 
} 

initialiseArray(); 
copyToNewArray(); 

Usted puede probar esto con bastante facilidad:

var x = []; 
console.log(x), x.push(5), x; // outputs [5] and [5] 
+0

Aún así, se podría pensar que renderizará/stringizará/resolverá la referencia de matriz en el punto adecuado, de lo contrario 'console.log'ging arrays casi nunca funcionaría. ¿Podría sucumbir Firefox a esto también, o es más inteligente? –

+0

@LightnessRacesinOrbit: No es más inteligente, sino que convierte todo en cadenas, así que sí debería funcionar. (FireBug, por otro lado ... no estoy seguro). – Ryan

+0

Propongo que eso sea "más inteligente", porque mantener la referencia tan tarde en este caso claramente viola POLS. (FWIW, quise decir Firebug) –

1

La consola es en realidad asíncrona. Debido a que está registrando una referencia a un objeto, para cuando se registra el objeto ya ha cambiado.

Puede clonar la matriz antes de iniciar sesión para asegurarse de que no se modifique antes de que se registre.

3

Como las matrices se pasan por referencia, cada cambio que realice le cambiará lo que se imprime en la consola. Es en parte el comportamiento de la consola de Chrome, en parte de JavaScript.

Si desea imprimir el resultado en el momento de la llamada al console.log, puede generarlo como una cadena usando JSON.stringify.

console.log("COPIED 1", JSON.stringify(copied_array)); 

editar Importante

Parece que era en su mayoría mal. Como diEcho señalado en los comentarios de la pregunta, un similar question tiene un better answer. Parece ser solo el comportamiento de Chrome.

+0

También encuentro este comportamiento en la consola de desarrollador web de Firefox (el navegador de valores es uno, no firebug). Entonces quizás no sea solo un comportamiento de Chrome. –

0

eso es porque el copied_array es una referencia, y console.log se ejecuta de manera asincrónica, por lo que el contenido de la matriz se modifica antes de que el primer registro lo imprima.

Puede copiar la matriz antes de imprimir

console.log([].concat(copied_array)); 
0

Si desea mantener la funcionalidad de la consola como la ampliación de los objetos en una matriz, se sugiere emplear .slice, que hace una copia de la matriz que no cambia al iniciar sesión :

console.log("COPIED 1", copied_array.slice()); 
+0

Bueno, pero el método JSON.stringify (copied_array) parece mejor, creo. –

Cuestiones relacionadas