2

I have a JavaScript object Team and a Score which represent points and some other functions. I want to know if it's safe to store the team in the score at the same time as storing the score in the team.

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

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

The result of this is that if I log team.score.team.score.team.score.team.score.team.score.points = 0. This is perfect for what I am programming, however does it represent a dangerous setup that may crash older browsers or cause any other issues? It looks exactly like an infinite loop however Chrome seems to be handling it fine.

Are there any reasons why I shouldn't do this?

NiRUS
  • 3,901
  • 2
  • 24
  • 50
Djave
  • 8,595
  • 8
  • 70
  • 124
  • 2
    I believe this is quite common practice! :) – SysVoid Oct 03 '16 at 10:16
  • 2
    Won't be stringified to JSON though. – Teemu Oct 03 '16 at 10:19
  • 3
    The looping aspect is fine. See `window.document.defaultView.document.defaultView` etc... – James Thorpe Oct 03 '16 at 10:20
  • If your code works and objective of question is *optimisation/improvements*, please post it on [CodeReviews](http://codereview.stackexchange.com/). – Rajesh Oct 03 '16 at 10:33
  • This is ok while it in browser, but you will have problems when sending such info for the server. I think Different servers - different problems. I had troubles in asp mvc 5. I've solved them with custom `ModelBinder`, but I spent time and now I'm always try not to use infinite loops in data definitions. Also I had one more problem with saving such structure to DB. – Nikita Oct 03 '16 at 10:41

3 Answers3

1

Good question by the way.

This is called circular referencing.

Meaning the you are creating the nested reference of the same object.

Garbage collection in browsers: The main function of the garbage collector in the browser is to free the memory if the memory occupied by the object is no longer in use. But in the case of circular reference

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)

(Source MDN)


This is forcing the garbage collecting algorithm to prevent the object from being garbage collected, which in turn is a memory leak.

As per the MDN Mark and sweep algorithm is been improved in such circumstance of circular referencing which is intelligent enough to remove the object of this type.

Circular referencing was a problem in IE < 8 which caused the IE browsers to go hay wire on this. Read this link and this one


IBM link

This article sheds light on JavaScript circular referencing memory leak with example and clarity on the subject.


Final Verdict: Better to avoid circular referenced objects, only use when its highly needed at programmers discretion. As modern browsers today are quite efficiently built though but its not a good practice as a developer to write code that causes unwanted memory consumption and leaks.

NiRUS
  • 3,901
  • 2
  • 24
  • 50
  • Great answer – memory leak was the phrase I was looking for when I typed infinite loop – Djave Oct 03 '16 at 13:14
  • 1
    The code posted by the OP did *not* cause problems in old IEs. The issue was only with circles involving DOM objects – Bergi Oct 03 '16 at 13:21
0

Diagrammatic Represation For Circular Referencing

Consider the code snippet below:

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

Here's a diagrammatic representation for the same: enter image description here

Now using the diagram above, follow the wires and try to answer what this expression obj.cirRef.cirRef.id evaluates to, the answer is 1.

Som Shekhar Mukherjee
  • 4,701
  • 1
  • 12
  • 28
-6
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);

Try this, maybe it can help you

Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
  • Welcome to SO! A good answer is one which not only gives verifiable example, but also explains what and why you have changed. This will help not only OP but everyone to learn something. – Rajesh Oct 03 '16 at 10:31
  • Thanks for Advice Rajesh :) I will take care of it next time – Piyush Joshi Oct 03 '16 at 10:41