为什么无限对象不会破坏javascript中的流程?

时间:2012-07-06 03:30:42

标签: javascript object recursion circular-reference

我在这里遇到的这种奇怪现象可能有一个特定的名称,这可能就是我在Google上找不到任何相关内容的原因。

我正在研究我的项目,我在检查员身上发现了一个奇怪的物体。我的代码在许多文件中被破坏了,同时发生了许多事情,所以我没有立即注意到,但是当我打开我的对象时,我发现它是无限的。

我会尝试在这里重现我的所作所为:

var monkey = {dad: 1, son: 1, have: null};
var banana = {state: 1, eatable: 1, have: null};

monkey.have = banana;
banana.have = monkey;

console.log(monkey);

如果您检查“猴子”对象,并展开“拥有”道具,您将看到它永远不会结束。因为香蕉总是有猴子和猴子总是有香蕉,递归。

(我认为这可能是因为javascript总是传递对象的引用而不是实际值。)

我在其他语言中看到过这种情况,但它总是阻止执行并引发明确的错误。

为什么javascript不会发生这种情况? 而且,更令人担心的是,这种代码在任何方面都是危险的吗?

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

现代浏览器的垃圾收集器非常智能,可以检测仅通过循环引用保持活动的对象并处理它们。很多语言都这样做;所有的.NET,Java,Ruby,Python ......实现起来并不困难。

答案 1 :(得分:2)

它被称为循环引用,它确实会导致某些浏览器出现问题(泄漏)。通常在IE中,当一个对象具有对DOM对象的循环引用(并且删除了DOM元素)时会导致内存泄漏。大多数现代浏览器都会考虑这种模式

答案 2 :(得分:2)

以下代码段说明两个属性都引用相同的 实例

http://jsfiddle.net/tyrmF/

var monkey = { name: "monkey boy", son: 1 };
var banana = { name: "ripe banana", eatable: 1 };

monkey.eats = banana;
banana.eatenby = monkey;

console.log(monkey);​

/* alerts "monkey boy" - original monkey instance */
alert(monkey.eats.eatenby.eats.eatenby.name);

请注意,当您继续“向下钻取”属性时,将保留对原始对象的引用(值相同)。

答案 3 :(得分:1)

两个对象实例,两个存储引用,这就是全部。没有任何内存泄漏的风险因为没有被复制,它只是给出了无限的“错觉”,但它总是指向相同的对象和为它们分配的相同内存。