今天我用javascript遇到了一些非常奇怪的行为。我想我现在已经弄清楚了,但是我想知道我认为发生的事情是否真的发生了,或者是否还有其他一些魔法。所以这是我的代码:
var SomeObject = {};
SomeObject.foo = function(a, b) {
var baz = this.bar(a, b);
console.log(baz);
console.log(baz.left);
SomeObject.magicalStuff(baz);
};
SomeObject.bar = function(a, b) {
return {left: a-b, top: b-a};
};
SomeObject.magicalStuff = function(position) {
position.left = 0;
};
SomeObject.foo(100, 50);
此输出类似于(取决于浏览器):
> Object
50
如果您展开“对象”(在Chrome,Safari或Firefox(Firebug)中,您获得的是:
> Object
left: 0
top: -50
我希望:
> Object
left: 50
top: -50
我的想法是,console.log()实际上只是“发布”对控制台的引用,一旦你点击“展开”符号就会被读取。但是那种打败console.log()作为调试工具的目的不是那样吗? 我总是希望console.log()能够“快照”我传递给它的东西。看到实际的console.log()改变了那个console.log()调用的输出之后的声明,真是令人惊讶。
或者还有其他事情发生了吗?
编辑:我也想知道浏览器开发人员是否有充分的理由像这样实现console.log(我猜有一个,否则它在主流浏览器中不一致)。
答案 0 :(得分:11)
Firebug中有console.dir()
你想要的东西。
通常,无法打印每个级别的嵌套属性,因为对象可以包含循环引用,如var a = {}; var b = {a: a}; a.b = b;
实现一个完美的clone
方法非常困难 - 我想它基本上只需要转储整个内存,并且日志记录会花费很长时间。想想console.log(window)
...
答案 1 :(得分:10)
是的,这是正在发生的事情。我猜这样做是为了尽量减少console.log()
次调用的开销。如果每个对象都被深度克隆用于每次日志调用,事情就会失控。
当我需要解决此问题时,我要先JSON.stringify()
或浅层对象,然后再将其传递给console.log()
。
答案 2 :(得分:6)