JavaScript Console Log Reporting Object Properties Incorrectly

In JavaScript Technology

The initial case was the usage of JS Fiddle, but to print the values of collection of objects console.log() is being used.

First step is initializing the object collection with some data (some objects) and console log it.

Then update this collection with some new data and console log it.

What is happening is that the first and second console logs are both identical, even though the object data was changed. The following is the initial code:

http://jsfiddle.net/n302nsbh/18/

function FooManager() {
    this.objects = {};

    this.update = function(data) {
        var self = this;
        $.each(data, function(i, e) {
            var foo = self.objects[i];
            if (typeof foo === "undefined") {
                foo = new Foo(e);
                self.objects[i] = foo;
            } else if (foo instanceof Foo) {
                foo.update(e);
            }
        });
    }
    return this;
}

function Foo(data) {
    this.name = data.name;
    this.age = data.age;
    return this;
}

Foo.prototype.update = function(data) {
    this.name = data.name;
    this.age = data.age;
}

//------ Update 1 --------//

var appData = {
    "0": {
        name: "a",
        age: 2
    },
    "1": {
        name: "b",
        age: 3
    }
}

var fooManager = new FooManager();
fooManager.update(appData);
console.log(fooManager.objects);

//------ Update 2 --------//

var newAppData = {
    "0": {
        name: "a",
        age: 443
    }
}

fooManager.update(newAppData);
console.log(fooManager.objects);

Both update 1 and update 2 logs are identical!

The problem in this case was that the browser doesn’t save the whole object when you call console.log(), just a reference to it. When you inspect it later, the browser will get the current version of the object.

You can test this quite simple by appending a new element to the object.

Call this at the end:

var newAppData = {
    "2": {
        name: "a",
        age: 443
    }
}

In the console it’ll show up as:

Object {0: Foo, 1: Foo}
Object {0: Foo, 1: Foo, 2: Foo}

but when you open the first log entry, you will see all three elements, so the browser inspects the current version.

Demo: https://jsfiddle.net/n302nsbh/22/

Solution 1

To see the current version of an element of the object, directly refer to it with console.log(fooManager.objects[0]); This will output for your script:

Foo {name: "a", age: 2}
Foo {name: "a", age: 443}

Demo: https://jsfiddle.net/n302nsbh/23/

Solution 2

Just found another nice solution at https://stackoverflow.com/a/7389177/1682509

Use console.log(JSON.parse(JSON.stringify(fooManager.objects))); to get a browsable snapshot.

Demo: https://jsfiddle.net/n302nsbh/24/

Click here to view original web page at stackoverflow.com