如何递归列出对象属性并将它们全部列在 'one-level-deep'-object 中?

How to recursively list object properties and list them all in a 'one-level-deep'-object?

我想做以下事情:我想从一个 JS 对象构建第二个对象,递归列出第一个对象的所有属性,但都在 'level one' 并且其名称是 'path' 在第一个对象中。

这是一个例子。以下对象...

{
    level1_simple: 'foo',
    level1_object: {
        level2_a: 'bar',
        level2_b: 'bar2'
    },
    level1_array: [
        {
            property1: 'foobar',
            property2: 'foobar2'
        },
        'element2'
    ]
}

应译为:

{
    level1_simple: 'foo',

    level1_object[level2_a]: 'bar',
    level1_object[level2_b]: 'bar2',

    level1_array[0][property1]: 'foobar',
    level1_array[0][property2]: 'foobar2',
    level1_array[1]: 'element2'
}

我写了一个递归函数,除了以下两个我无法解决的问题外,它运行良好:

  1. 字符串被解析为字符数组而不是字符串
  2. 我不知道如何检测 'leaf' 属性(终止条件),因为每个 属性 似乎总是有一个 '0' 属性,它本身有一个'0'属性,等等

这是完整的代码(由于上面的第 2 点导致无限循环):

function _treatDataRecursive( data, newData, prefix )
{
    console.log( 'Entering: ' + prefix +"\n" );

    // Iterate over the properties of data
    for( property in data )
    {
        console.log( 'Listing properties: ' + property + " value = " + data[property] + "\n" );
        // Build property symfonyzed name (using recursion)
        var newPropName = prefix + '[' + property + ']';
        // Check if property is a leaf
        var type = typeof property;
        if( type === 'string' || type === 'number' || type === 'boolean' )
        {
            console.log( 'Property is a leaf: ' + property +"\n" );
            // Property is a leaf: add property/value to newData
            newData[newPropName] = data[property];
        } else {
            // Recursive call to go one level deeper
            _treatDataRecursive( property, newData, newPropName );
        }
    }
}

你只有一个大问题。您应该使用 property 的实际值,而不是 property 本身。

function _treatDataRecursive(data, newData, prefix) {
    for (var property in data) {
        // if prefix is empty, don't decorate the property
        var newPropName = prefix ? prefix + '[' + property + ']' : property;
        // get the type of the actual value, not the `property`
        var type = typeof data[property];

        // If it is an object and not null do the recursion
        if (type === 'object' && data[property] !== null) {
            _treatDataRecursive(data[property], newData, newPropName);
        } else {
            // Most likely a leaf, don't recurse now
            newData[newPropName] = data[property];
        }
    }
}

var obj = {};
_treatDataRecursive(data, obj, "");
console.log(obj);

输出

{ level1_simple: 'foo',
  'level1_object[level2_a]': 'bar',
  'level1_object[level2_b]': 'bar2',
  'level1_array[0][property1]': 'foobar',
  'level1_array[0][property2]': 'foobar2',
  'level1_array[1]': 'element2' }