你不需要递归!
以下函数函数将按从最深到最深的顺序输出条目,并将键的值作为[key, value]
数组输出。
function deepEntries( obj ){
'use-strict';
var allkeys, curKey = '[', len = 0, i = -1, entryK;
function formatKeys( entries ){
entryK = entries.length;
len += entries.length;
while (entryK--)
entries[entryK][0] = curKey+JSON.stringify(entries[entryK][0])+']';
return entries;
}
allkeys = formatKeys( Object.entries(obj) );
while (++i !== len)
if (typeof allkeys[i][1] === 'object' && allkeys[i][1] !== null){
curKey = allkeys[i][0] + '[';
Array.prototype.push.apply(
allkeys,
formatKeys( Object.entries(allkeys[i][1]) )
);
}
return allkeys;
}
然后,要输出您正在寻找的结果类型,只需使用它。
function stringifyEntries(allkeys){
return allkeys.reduce(function(acc, x){
return acc+((acc&&'\n')+x[0])
}, '');
};
如果您对技术位感兴趣,那么这就是它的工作原理。它的工作原理是获取您传递Object.entries
的obj
对象的 并将它们放入数组中allkeys
。然后,从开始allkeys
到结束,如果它发现allkeys
条目值之一是一个对象,则它获取该条目的键为curKey
,并curKey
在将结果数组推送到结束之前为其每个自己的条目键添加前缀allkeys
。然后,它将添加的条目数添加到allkeys
目标长度,以便它也将遍历那些新添加的键。
例如,请注意以下事项:
<script>
var object = {
aProperty: {
aSetting1: 1,
aSetting2: 2,
aSetting3: 3,
aSetting4: 4,
aSetting5: 5
},
bProperty: {
bSetting1: {
bPropertySubSetting : true
},
bSetting2: "bString"
},
cProperty: {
cSetting: "cString"
}
}
document.write(
'<pre>' + stringifyEntries( deepEntries(object) ) + '</pre>'
);
function deepEntries( obj ){//debugger;
'use-strict';
var allkeys, curKey = '[', len = 0, i = -1, entryK;
function formatKeys( entries ){
entryK = entries.length;
len += entries.length;
while (entryK--)
entries[entryK][0] = curKey+JSON.stringify(entries[entryK][0])+']';
return entries;
}
allkeys = formatKeys( Object.entries(obj) );
while (++i !== len)
if (typeof allkeys[i][1] === 'object' && allkeys[i][1] !== null){
curKey = allkeys[i][0] + '[';
Array.prototype.push.apply(
allkeys,
formatKeys( Object.entries(allkeys[i][1]) )
);
}
return allkeys;
}
function stringifyEntries(allkeys){
return allkeys.reduce(function(acc, x){
return acc+((acc&&'\n')+x[0])
}, '');
};
</script>
或者,如果您只想要属性,而不想要具有属性的对象,那么您可以像这样过滤掉:
deepEntries(object).filter(function(x){return typeof x[1] !== 'object'});
例子:
<script>
var object = {
aProperty: {
aSetting1: 1,
aSetting2: 2,
aSetting3: 3,
aSetting4: 4,
aSetting5: 5
},
bProperty: {
bSetting1: {
bPropertySubSetting : true
},
bSetting2: "bString"
},
cProperty: {
cSetting: "cString"
}
}
document.write('<pre>' + stringifyEntries(
deepEntries(object).filter(function(x){
return typeof x[1] !== 'object';
})
) + '</pre>');
function deepEntries( obj ){//debugger;
'use-strict';
var allkeys, curKey = '[', len = 0, i = -1, entryK;
function formatKeys( entries ){
entryK = entries.length;
len += entries.length;
while (entryK--)
entries[entryK][0] = curKey+JSON.stringify(entries[entryK][0])+']';
return entries;
}
allkeys = formatKeys( Object.entries(obj) );
while (++i !== len)
if (typeof allkeys[i][1] === 'object' && allkeys[i][1] !== null){
curKey = allkeys[i][0] + '[';
Array.prototype.push.apply(
allkeys,
formatKeys( Object.entries(allkeys[i][1]) )
);
}
return allkeys;
}
function stringifyEntries(allkeys){
return allkeys.reduce(function(acc, x){
return acc+((acc&&'\n')+x[0])
}, '');
};
</script>
浏览器兼容性
上述解决方案在 IE 中不起作用,而只能在 Edge 中起作用,因为它使用了 Object.entries 函数。如果您需要 IE9+ 支持,那么只需将以下Object.entries
polyfill添加到您的代码中。如果您出于某种原因,实际上确实需要 IE6+ 支持,那么您还需要一个Object.keys
和JSON.stringify
polyfill(此处均未列出,因此请在其他地方找到)。
if (!Object.entries)
Object.entries = function( obj ){
var ownProps = Object.keys( obj ),
i = ownProps.length,
resArray = new Array(i); // preallocate the Array
while (i--)
resArray[i] = [ownProps[i], obj[ownProps[i]]];
return resArray;
};