Z
In order to cross all fields and learn the meanings, we could count the field's investment and write a recurring function that would overtake a certain amount of properties in the object, for example, something like function getProp(obj) {
for(var prop in obj) {
if(typeof(obj[prop]) === 'object') {
console.log(obj[prop])
for(var prop2 in obj[prop]) {
if(typeof(obj[prop][prop2]) === 'object') {
console.log(obj[prop][prop2])
//... другие вложенные циклы for...in
}
}
}
}
}
But it's a bad decision, because we're forced to duplicate the code, it's going to be cumbersome, and we can't be sure that the object transferred to the challenge will preserve the same number of fields we've put on.Therefore, a more appropriate use will be made of a transcurring function that does not depend on a specific number of capacity levels. For example:function getFiniteValue(obj) {
getProp(obj);
function getProp(o) {
for(var prop in o) {
if(typeof(o[prop]) === 'object') {
getProp(o[prop]);
} else {
console.log('Finite value: ',o[prop])
}
}
}
}
var fractal = {
a1: {
b1: {
c: 1
},
b2: {
c: 222
},
b3: {
c: {
d: 33,
e: 2.5,
f: {
g: 9999,
h: {
i: {
j: 1001,
k: 'строка',
l: [1,2,3]
}
}
}
}
}
}
}
getFiniteValue(fractal);
function getFiniteValue(obj) {
getProp(obj);
function getProp(o) {
for(var prop in o) {
if(typeof(o[prop]) === 'object') {
getProp(o[prop]);
} else {
console.log('Finite value: '+o[prop])
}
}
}
}Example https://jsfiddle.net/Romanzhivo/9e3rvp6x/ However, as the commentaries noted, https://ru.stackoverflow.com/users/32625/yaant There is an invisible problem: if one of the properties of the facility is a cyclical reference, i.e., to refer to one of its parenting properties, the recurring challenge of the function will be endless, resulting in overcrowded functions.The solution to the problem could be to keep information on the fact that the object was overtaken in the cycle and to report that the object had a cyclical link. To this end, the cycle facility may be added a temporary flag and then removed. It's better to choose the most unique name so it doesn't coincide with the properties already in place. For example, we'll record the temporal properties. temp__isAlreadyHandled_ Each object that has been processed in the cycle and then remove this characteristic:function getFiniteValue(obj) {
var handledFlag = 'temp__isAlreadyHandled__';
getProp(obj);
function getProp(o, stack) {
var propertyPath;
for(var prop in o) {
if(typeof(o[prop]) === 'object') {
if(!o[prop][handledFlag]) {
Object.defineProperty(o[prop],handledFlag, {
value: true,
writable:false,
configurable: true
});
if(!stack)
propertyPath = 'rootObject.' + prop
else
propertyPath = stack + '.' + prop;
getProp(o[prop], propertyPath);
} else {
propertyPath = stack + '.' + prop;
console.error('Циклическая ссылка. Свойство: ' + propertyPath);
}
delete o[prop][handledFlag]
} else {
console.log('Finite value: ',o[prop])
}
}
}
}
var fractal = {
a1: {
b1: {
c: 1
},
b2: {
c: 222
},
b3: {
c: {
d: 33,
e: 2.5,
f: {
g: 9999,
h: {
i: {
j: 1001,
k: 'строка',
l: [1,2,3]
}
}
}
}
}
}
}
fractal.a1.b2.m = fractal.a1.b2;
getFiniteValue(fractal);
function getFiniteValue(obj) {
var handledFlag = 'temp__isAlreadyHandled__';
getProp(obj);
function getProp(o, stack) {
var propertyPath;
for(var prop in o) {
if(typeof(o[prop]) === 'object') {
if(!o[prop][handledFlag]) {
Object.defineProperty(o[prop],handledFlag, {
value: true,
writable:false,
configurable: true
});
if(!stack)
propertyPath = 'rootObject.' + prop
else
propertyPath = stack + '.' + prop;
getProp(o[prop], propertyPath);
} else {
propertyPath = stack + '.' + prop;
console.error('Циклическая ссылка. Свойство: ' + propertyPath);
}
delete o[prop][handledFlag]
} else {
console.log('Finite value: ',o[prop]);
}
}
}
}Example https://jsfiddle.net/Romanzhivo/q29o8ehf/ In more detail in the article http://romanzhivo.com/%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D1%8B%D0%B9-%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%BE%D1%80-%D0%B2%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA/