Нет хорошего способа обнаружить округлость в объектах, но это возможно, хотя, обходя дерево объектов и проверяя ссылки.Я запустил функцию ходьбы по узлу, которая пытается определить, был ли узел уже использован в качестве его родителя
function isCircularObject(node, parents){
parents = parents || [];
if(!node || typeof node != "object"){
return false;
}
var keys = Object.keys(node), i, value;
parents.push(node); // add self to current path
for(i = keys.length-1; i>=0; i--){
value = node[keys[i]];
if(value && typeof value == "object"){
if(parents.indexOf(value)>=0){
// circularity detected!
return true;
}
// check child nodes
if(arguments.callee(value, parents)){
return true;
}
}
}
parents.pop(node);
return false;
}
И использование будет isCircularObject(obj_value)
, где функция возвращает true
, если существует цикличность, иfalse
если нет.
// setup test object
var testObj = {
property_a:1,
property_b: {
porperty_c: 2
},
property_d: {
property_e: {
property_f: 3
}
}
}
console.log(isCircularObject(testObj)); // false
// add reference to another node in the same object
testObj.property_d.property_e.property_g = testObj.property_b;
console.log(isCircularObject(testObj)); // false
// add circular node
testObj.property_b.property_c = testObj.property_b;
console.log(isCircularObject(testObj)); // true
Ключевым моментом является то, что значение объекта равно другому значению только , если это та же ссылка на объект, а не когда это другой объект (даже если полностью похожи).