Comportamiento errático de Javascript o código incorrecto por mí, los valores de matriz aumentaron antes de la operación real

I have a bunch of javascript functions, that trigger upon button clicks. So assuming we have two button s that trigger two methods such as:

 var universal = false;
    var collection = Array(); // assume it has 5 data elements( 0...4) upon page load

    function next()
    {
      if(universal)
         addToArray();

       // do whatever else
    }

    function addToArray()
    {

        console.log(collection);
       // perform some DOM calls,that simply Hide/change position of elements
       var newElement = 'some info';   
       collection.push(newElement);
    }

In the above addToArray() function, it is called upon when 'next' button is clicked and the universal variable is set to true. At this point we enter, addToArray() method and a console.log is invoked to check out 'collection'.

This, at any given point, should be not more than 5 elements since addToArray will eventually add an element to collection but not right at the start. However, the console.log shows that collection has the new element added, which was actually supposed to be added during the addToArray method() not right off the bat.

I know this sounds really goofy, but this is what I am getting. I am trying to understand if asynchronous behavior has anything to do with it.

preguntado el 17 de diciembre de 12 a las 22:12

2 Respuestas

If you're using Chrome, the reason is that console.log registra un para vivir version of the object that updates in the console window when you change it later.

Si cambias

console.log(collection);

A ...

console.log(collection.join(","));

...or probably more usefully

console.log(JSON.stringify(collection));

...you'll see a point-in-time version of the array.

El comportamiento de console.log is actually quite tricky, although consistent once you get your head 'round it. For instance, consider this code:

var a = [1, 2, 3];

console.log("first");
console.log(a);
console.log("second");
a[0] = '11';
a = ['a', 'b', 'c'];
console.log("third");

Copia en vivo | Fuente

If you have the console open when you run that, you see:

en el primer
[1, 2, 3]
second
third

...and no amount of clicking on that [1, 2, 3] te mostrara el "11" the code put at index 0, much less the new array we put in a.

Pero si cambias el

var a = [1, 2, 3];

A ...

var a = [[1, 1], 2, 3];

Copia en vivo | Fuente

...ves esto:

en el primer
>[Array[2], 2, 3]
second
third

...and clicking the arrow next to the array changes it to this:

en el primer
v[Array[2], 2, 3]
    0: "11"
    1: 2
    2: 3
    length: 3
    __proto__: Array[0]
second
third

...which looks a bit non-sensical.

Pero make sense, you have to think in terms of the console having a referencia to the thing you asked it to output. It outputs a line for the thing, and esa linea is static. But because it saw that the object graph went deeper, Chrome put an arrow next to the array so you could expand it. When you click the array, the new lines added to the output are generated luego, mirando el now current version of the object, which has obviously changed since the first line was output. Tricky, eh?

In the comments, epascarello mentions using console.dir instead, but that just makes it even more reliably "live," rather than being a point-in-time record.

Respondido el 17 de diciembre de 12 a las 23:12

or console.dir(collection) - epascarello

that's interesting. I declared a variable x = 2.0 , outside of my function, logged in console.log(x) and then towards the end of my function I said x = x*2.0, and then console.log(x), in this case, it first spat out 2, and then 4, the way it should be. Why did it not use a live version of the object in this situation ? - Parijat Kalia

@ParijatKalia: Because numbers are not reference types. If you do var a = [1, 2, 3]; console.log(a); a = ['a', 'b', 'c']; you don't see that change for the same reason you don't see the change to the number. - TJ Crowder

ok one more thing, the array consists of objects, so using a join to convert them into a comma separated string is not helpful, any suggestions to break this ? - Parijat Kalia

@epascarello: I'm not seeing any difference with console.dir. I get a live copy of the array with that as well -- actually, a more reliably live copy. - TJ Crowder

Your issue is probably that console.log is asynchronous. Try commenting it out or putting a timeout/breakpoint in that line.

Respondido el 17 de diciembre de 12 a las 22:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.