JavaScript 对象的子对象可以引用自身吗?

Can a JavaScript object's child reference itself?

我有一个 JavaScript 对象 Team 和一个 Score 代表点和一些其他功能。我想知道在将分数存储在团队中的同时将团队存储在分数中是否安全。

var Score = function(team){
    this.team = team;
    this.points = 0;
    ...
}

var team = {
    name : 'Team 1',
}
team.score = new Score(team);

结果是,如果我登录 team.score.team.score.team.score.team.score.team.score.points = 0。这对我正在编程的内容来说是完美的,但是它是否代表一个危险的设置,可能会导致旧浏览器崩溃或导致任何其他问题?它看起来完全像一个无限循环,但是 Chrome 似乎处理得很好。

我有什么理由不应该这样做吗?

var Score = function(team,point){
    this.team = team;
    this.points = 0;
    ...
}

var team = {
    name : 'Team 1',
   point : 'point'
}
team.score = new Score(team);
team.score = new Score(point);

试试这个,也许它能帮到你

顺便问个好问题。

这叫做循环引用

这意味着您正在创建同一对象的嵌套引用。

浏览器中的垃圾收集: 浏览器中垃圾收集器的主要作用是在对象占用的内存不再使用时释放内存。但是在循环引用的情况下

An object is said to reference another object if the former has an access to the latter (either implicitly or explicitly). For instance, a JavaScript object has a reference to its prototype (implicit reference) and to its properties values (explicit reference)

(来源MDN


这是强制垃圾收集算法阻止对象被垃圾收集,这反过来又是内存泄漏。

根据 MDN Mark and sweep algorithm 在这种循环引用的情况下得到了改进,它足够智能以删除这种类型的对象。

循环引用是 IE < 8 中的一个问题,它导致 IE 浏览器在此问题上失控。阅读此 link and this one


IBM link

本文通过示例清楚地阐明了 JavaScript 循环引用内存泄漏。


最终判决: 最好避免循环引用对象,仅在程序员自行决定非常需要时才使用。尽管当今的现代浏览器构建起来非常高效,但作为开发人员编写会导致不必要的内存消耗和泄漏的代码并不是一个好习惯。

循环引用的图示

考虑下面的代码片段:

const obj = {
  id: 1
};
obj.cirRef = obj;

console.log(obj.cirRef === obj); // true
console.log(obj.cirRef.cirRef === obj); // true
console.log(obj.cirRef.cirRef.cirRef.cirRef.id); // 1

这是相同的图形表示:

现在使用上图,按照连线尝试回答这个表达式 obj.cirRef.cirRef.id 的计算结果,答案是 1.