在JavaScript中压缩对象层次结构

AnC*_*AnC 10 javascript json coffeescript

是否存在将嵌套对象"压缩"到单个级别的通用方法:

var myObj = {
    a: "hello",
    b: {
        c: "world"
    }
}

compress(myObj) == {
    a: "hello",
    b_c: "world"
}
Run Code Online (Sandbox Code Playgroud)

我想会有一些递归,但我想我不需要在这里重新发明轮子......!?

Mat*_*ley 21

function flatten(obj, includePrototype, into, prefix) {
    into = into || {};
    prefix = prefix || "";

    for (var k in obj) {
        if (includePrototype || obj.hasOwnProperty(k)) {
            var prop = obj[k];
            if (prop && typeof prop === "object" &&
                !(prop instanceof Date || prop instanceof RegExp)) {
                flatten(prop, includePrototype, into, prefix + k + "_");
            }
            else {
                into[prefix + k] = prop;
            }
        }
    }

    return into;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过传入true第二个参数来包含成员继承的成员.

一些警告:

  • 递归对象将无法正常工作.例如:

    var o = { a: "foo" };
    o.b = o;
    flatten(o);
    
    Run Code Online (Sandbox Code Playgroud)

    将递归,直到它抛出异常.

  • 像ruquay的答案一样,这就像普通的对象属性一样拉出数组元素.如果要保持数组完整,请|| prop instanceof Array在异常中添加" ".

  • 如果在来自不同窗口或框架的对象上调用此方法,则不会包含日期和正则表达式,因为instanceof无法正常工作.您可以通过将其替换为默认的toString方法来解决此问题,如下所示:

    Object.prototype.toString.call(prop) === "[object Date]"
    Object.prototype.toString.call(prop) === "[object RegExp]"
    Object.prototype.toString.call(prop) === "[object Array]"
    
    Run Code Online (Sandbox Code Playgroud)