4

I've run into a rather interesting problem. The code below generates an array that, when logged, gives the value [undefined × 1]. According to this answer, that means that the array has unitialized indexes--in this case, only one. However, since I'm only using array.push() to avoid exactly this sort of problem, I'm kind of lost. To the best of my knowledge only assigning an index at least one index greater than other initialized indexes could cause the problem. Anyhow, here's the code:

function Thing(params) {
    var that = this;

    this.OtherObject = function OtherObject(param) {
        this.param = param;
    }

    this.Foo = function Foo() {
        this.bar = [];

        this.add = function(item) {
            if (this.bar.length != 0) {
                for (var i = 0, len = this.bar.length; i < len; i++) {
                    if (this.bar[i].param <= item.param) {
                        this.bar.splice(i, 0, item);
                    }
                }
            } else {
                this.bar[0] = item;
                console.log(this.bar);
            }
        }

        this.pop = function() {
            return this.bar.pop();
        }

        this.length = function() {
            return this.bar.length;
        }
    }

    this.someFunc = function() {
        var myThing = new that.Foo();
        myThing.add(new that.OtherObject(3));

        while (myThing.length() > 0) {
            var someVar = myThing.pop();
        }
    }
}

var myThing = new Thing({
    myParam: "someValue"
});

myThing.someFunc();
​

I created a test case to see if I could narrow the problem down, but I ended up re-typing 95% of my code until I ran into the issue again, which appears to be related with my use of myThing.pop(). You can find a fiddle here which demonstrates the issue in question.

So... any ideas as to what could be causing this? Is this actually a problem with the way I've nested my objects? (which I did following a pattern given to me in this answer to a previous question of mine).

In case you're wondering what I could possibly be trying to do here, I'm treating the outside object like a sort of namespace, which I'm doing to avoid cluttering up the global namespace (this will eventually be a pathfinding library, if I get my act together here). The Foo object is meant to be a sort of ordered list such that I can get the closest node (the one with the lowest param property) by pop()ing the stack.

Community
  • 1
  • 1
Elliot Bonneville
  • 51,872
  • 23
  • 96
  • 123
  • What browser are you testing this in? Have you tried any others? – loganfsmyth May 26 '12 at 03:41
  • You may want to double-check that the value is actually incorrect. It was showing up just empty for me, which is still weird, until I remembered that Chrome dynamically updates some console.log output. So because you were popping later, it was updating the printed array to display as empty. Or something. If you do console.log(this.bar.toString()), do you see the item? – loganfsmyth May 26 '12 at 03:52

1 Answers1

2

There is just something going on that is very strange with Google Chrome's console.log function. Other browsers seem to behave as you would expect. This is one one of the weirder things I've seen: if you add a call to alert after the lne that calls console.log, there will be different output in the console.

console.log(this.bar);
alert(this.bar);

// [> OtherObject]

If you remove the alert, as you have seen, the console will output

// [undefined × 1] 

This sort of thing is either due to some race condition or some side effect that the alert function is causing. Here's my theory on what's going on behind the scenes:

  • The console.log function does not actually log values in the console until there is some halt in the code, and then it logs all the queued messages. The queue contains references to the messages that are to be logged.
  • The first item in this.bar is destroyed when you pop the array. The logger, unless there is some interruption, will display the message after the referenced value is destroyed. Thus, it displays [undefined × 1]
  • Calling alert causes a halt in the code so that the console can log the message before the referenced value is erased.

I'm still not completely sure if this is really what's happening, but it seems to be somwhat reasonable. I'll do some more testing to check if my theory is correct.

Peter Olson
  • 139,199
  • 49
  • 202
  • 242