仅使用Array_push时,数组中未初始化的变量?

时间:2012-05-26 02:59:06

标签: javascript

我遇到了一个相当有趣的问题。下面的代码生成一个数组,在记录时,它给出值[undefined × 1]。根据{{​​3}},这意味着数组具有单元化索引 - 在这种情况下,只有一个。但是,由于我只使用array.push()来避免这种问题,我有点迷茫。据我所知,只分配索引至少一个索引大于其他初始化索引可能导致问题。无论如何,这是代码:

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();
​

我创建了一个测试用例,看看我是否可以缩小问题,但最后我重新输入了95%的代码,直到我再次遇到问题,这似乎与我使用{{1 }}。你可以找到一个小提琴this answer来证明这个问题。

那么......关于可能导致这种情况的任何想法?这实际上是我嵌套对象的方式的问题吗? (我按照here给我的一个模式对我之前的问题进行了测试。

如果您想知道我可能在这里尝试做什么,我将外部对象视为一种命名空间,我正在做的是为了避免混乱全局命名空间(这最终将是一个寻路库,如果我在这里得到我的行为)。 myThing.pop()对象应该是一种有序列表,这样我就可以通过Foo堆栈获得最近的节点(具有最低param属性的节点)。

1 个答案:

答案 0 :(得分:2)

谷歌Chrome的console.log功能正在发生一些非常奇怪的事情。其他浏览器似乎表现得像您期望的那样。这是我见过的最奇怪的事情之一:如果在调用alert的lne之后添加对console.log的调用,则控制台中将有不同的输出。

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

// [> OtherObject]

如果您删除alert,正如您所见,控制台将输出

// [undefined × 1] 

这种情况要么是由于一些竞争条件,要么是由alert函数引起的一些副作用。这是关于幕后发生的事情的理论:

  • console.log函数实际上不会在控制台中记录值,直到代码中有一些停顿,然后它会记录所有排队的消息。队列包含对要记录的消息的引用。
  • 弹出数组时,this.bar中的第一项将被销毁。除非存在中断,否则记录器将在销毁引用值后显示消息。因此,它显示[undefined × 1]
  • 调用alert会导致代码暂停,以便控制台可以在删除引用值之前记录消息。

我仍然不完全确定这是否真的发生了什么,但似乎是合理的。我会做一些测试来检查我的理论是否正确。