访问对象的属性时,我遇到了极其奇怪的行为。
运行此代码:
console.log(myObj);
console.log(myObj.items);
console.log(myObj);
我在控制台中输出了这个输出:
这怎么可能发生?
答案 0 :(得分:7)
console.log
,在执行期间,在控制台中输出值的字符串表示形式。根据Chrome的情绪,它可能会显示[object Object]
或Object {}
之类的内容。这没关系。
现在请注意旁边的小蓝i
。这意味着对象在记录时间和在控制台中展开它的时间之间进行了修改,它现在显示当前值(带有2个项目),而不是值在console.log
执行期间(没有项目)。您实际上可以将鼠标悬停在蓝色i
上以获得解释。
要复制该问题,请打开控制台并运行此代码段:
var obj = {arr: []};
console.log(obj);
console.log(obj.arr);
console.log(obj);
// by this time, you see 2 object logs, 1 empty array
// (representation differs from time to time)
// > Object
// []
// > Object
obj.arr.push(1,2);
// when you try to expand the objects, an array of 2 items magically appear
// but you still see the empty array ([]) in the log.

此行为因浏览器而异。据我所知,Firebug在执行console.log
时会输出序列化版本,因此不会发生这种情况。
要调试此类代码,您有以下几种选择:
最快捷的方法是使用JSON.stringify
记录对象的字符串版本,例如console.log(JSON.stringify(obj))
;
最好的方法是通过Sources选项卡添加断点。在Dev Tools的Sources选项卡中浏览到您的文件,并在该位置添加断点。运行您的代码,它将在此时暂停。使用“范围”面板检查变量。
如果您无法使用断点(可能使用eval
运行或在控制台中注入)来访问代码,则可以使用debugger;
语句。只需将其放在该位置的代码中即可。运行代码,它会在到达语句时暂停。使用“源”选项卡中的“范围”面板进行检查。
答案 1 :(得分:1)
您可以查看要检查的对象的JSON表示,您可以使用:
mplus
答案 2 :(得分:1)
由于信息太少,我只能假设您动态填充items
属性,在第二个控制台日志运行时将其设为空。
现在你想知道为什么它存在于第一个控制台日志中:控制台没有显示记录对象时那里的对象属性,而是在对象输入时在控制台中进行了扩展,因此可能是在第二个控制台日志之后和扩展第一个控制台日志之前填充了items
。尝试将对象记录为字符串或JSON,以查看控制台日志运行时的实际状态。
底线:只有当您展开对象条目(当您单击箭头时)时,开发控制台中的对象属性才会更新,因此您无法看到对象的实际表示形式记录的时间。
这是一个简单的演示 - 看看它甚至可以从一个数组变成一个字符串:
var obj = {p: []}
console.log(obj);
setTimeout(function(){
obj.p = "I'm not even an array!";
}, 1000);