我遇到了一个相当有趣的问题。下面的代码生成一个数组,在记录时,它给出值[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
属性的节点)。
答案 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
会导致代码暂停,以便控制台可以在删除引用值之前记录消息。我仍然不完全确定这是否真的发生了什么,但似乎是合理的。我会做一些测试来检查我的理论是否正确。