我了解的这段代码。我们复制A并将其称为C。当A更改时,C保持不变
var A = 1; var C = A; console.log(C); // 1 A++; console.log(C); // 1
但是当A是一个数组时,我们会有不同的情景。C不仅会改变,而且甚至在我们碰到A之前都会改变
var A = [2, 1]; var C = A; console.log(C); // [1, 2] A.sort(); console.log(C); // [1, 2]
有人可以解释第二个示例中发生的情况吗?
Pointy的答案有很好的信息,但这不是此问题的正确答案。
OP所描述的行为是一个错误的一部分,该错误于2010年3月首次报告,并于2012年8月为Webkit进行了修补,但截至本文撰写之时尚未集成到GoogleChrome中。行为取决于将对象文字传递到时控制台调试窗口是 打开 还是 关闭console.log()。
console.log()
):
Description from mitch kramer 2010-03-05 11:37:45 PST 1)创建具有一个或多个属性的对象文字 2)console.log该对象,但保持关闭状态(不要在控制台中扩展它) 3)将其中一个属性更改为新值 现在打开该console.log,您会发现由于某些原因它具有新值,即使它的值在生成时有所不同。 我应该指出,如果您打开它,它将保持正确的值(如果不清楚)。
Description from mitch kramer 2010-03-05 11:37:45 PST
1)创建具有一个或多个属性的对象文字
2)console.log该对象,但保持关闭状态(不要在控制台中扩展它)
3)将其中一个属性更改为新值
现在打开该console.log,您会发现由于某些原因它具有新值,即使它的值在生成时有所不同。
我应该指出,如果您打开它,它将保持正确的值(如果不清楚)。
Chromium开发人员的回复:
评论#2来自帕维尔·费尔德曼(Pavel Feldman)2010-03-09 06:33:36 PST 我认为我们永远都不会解决这个问题。我们无法在将对象转储到控制台中后对其进行克隆,也无法监听对象属性的更改以使其始终真实。 但是,我们应该确保预期存在的行为。
评论#2来自帕维尔·费尔德曼(Pavel Feldman)2010-03-09 06:33:36 PST
我认为我们永远都不会解决这个问题。我们无法在将对象转储到控制台中后对其进行克隆,也无法监听对象属性的更改以使其始终真实。
但是,我们应该确保预期存在的行为。
随之而来的是许多抱怨,最终导致错误修复。
从今天开始,将对象(数组)转储到控制台中将导致在扩展控制台对象时(即,延迟地)读取对象的属性。这意味着在突变时转储相同的对象将很难使用控制台进行调试。 此更改会在记录对象/数组时开始为其生成简短的预览,并将此信息传递到前端。这仅在前端已打开时发生,它仅适用于console.log(),不适用于实时控制台交互。
从今天开始,将对象(数组)转储到控制台中将导致在扩展控制台对象时(即,延迟地)读取对象的属性。这意味着在突变时转储相同的对象将很难使用控制台进行调试。
此更改会在记录对象/数组时开始为其生成简短的预览,并将此信息传递到前端。这仅在前端已打开时发生,它仅适用于console.log(),不适用于实时控制台交互。
Console.log()传递了对该对象的引用,因此控制台中的值随对象的变化而变化。为避免这种情况,你可以:
Console.log()
console.log(JSON.parse(JSON.stringify(c)))
MDN警告:
请注意,如果你在最新版本的Chrome和Firefox中记录对象,则在控制台上登录的内容是对该对象的引用,这不一定是调用时对象的“值” console.log(),而是它是打开控制台时对象的值。