如果对象不存在,则将缺少的属性添加到具有空值的对象

Dan*_*nny 2 javascript

我有一组具有不同属性的对象:

var arr = [];

var obj_1 = {
    'key_a': 'value_a',
    'key_b': 'value_b'
};

arr.push(obj_1);

var obj_2 = {
    'key_a': 'value_a',
    'key_b': 'value_b',
    'key_c': 'value_c'
};

arr.push(obj_2);
Run Code Online (Sandbox Code Playgroud)

如果数组中的每个对象都不存在,我如何自动将新键(key_c)或任何其他键添加到数组中的每个对象?

所以数组看起来像这样:

    [
        {
            'key_a': 'value_a'
            'key_b': 'value_b'
            'key_c': ''
        },
        {
            'key_a': 'value_a'
            'key_b': 'value_b'
            'key_c': 'value_c'
        }
    ]
Run Code Online (Sandbox Code Playgroud)

请注意:我正在构建一个Web scraper,未知的键/属性将添加到对象中并在foreach循环中推送到数组.

T.J*_*der 5

如果数组中的每个对象都不存在,我如何自动将新键(key_c)或任何其他键添加到数组中的每个对象?

你必须旋转数组,检查每个对象是否还有它们尚未拥有的键,然后添加它们,这将是一个痛苦的过程.

相反,您可以拥有一个原型对象,其中所有属性都具有默认值,并在所有具体对象后面使用该原型.当您了解新密钥时,使用默认值将它们添加到原型中,并且它们似乎可以追溯地在所有先前对象上神奇地出现(因为您正在修改它们背后的原型).稍后从对象获取属性时,它们将使用自己的值来获取它们拥有的属性,并使用原型中的默认值来获取它们不具有的属性.

要使用另一个对象作为其原型来创建对象,请使用Object.create:

obj = Object.create(defaults); // defaults is the prototype object to use
Run Code Online (Sandbox Code Playgroud)

如果您正在接收需要从其他地方跟踪的对象(例如,您没有创建它们),您可以使用函数使用"默认值"创建对象,然后复制您收到的对象的任何属性.这也是一个标记您还不知道的任何新属性并为其设置默认值的机会:

var defaults = {};
var list = [];

function addToList(obj) {
    // Create our entry backed by the defaults
    var entry = Object.create(defaults);

    // Loop through the new object's keys...
    Object.keys(obj).forEach(function(key) {
        // ...adding a default if it's a new key
        if (!defaults.hasOwnProperty(key)) {
            defaults[key] = /*...default value...*/;
        }
        // ...and grabbing the value
        entry[key] = obj[key];
    });

    // Put it on the list
    list.push(entry);
}
Run Code Online (Sandbox Code Playgroud)

实例:

var defaults = {};
var list = [];

function addToList(obj) {
  // Create our entry backed by the defaults
  var entry = Object.create(defaults);
  
  // Loop through the new object's keys...
  Object.keys(obj).forEach(function(key) {
    // ...adding a default if it's a new key
    if (!defaults.hasOwnProperty(key)) {
      defaults[key] = "default for " + key;
    }
    // ...and grabbing the value
    entry[key] = obj[key];
  });
  
  // Put it on the list
  list.push(entry);
}

addToList({a: "a0", b: "b0"}); // Has a and b
addToList({a: "a1", c: "c1"}); // Has a and c
addToList({b: "b2", d: "d2"}); // Has b and d

list.forEach(function(entry, index) {
  snippet.log("Object #" + index + ":");
  Object.keys(defaults).forEach(function(key) {
    snippet.log(key + " = " + entry[key]);
  });
});
Run Code Online (Sandbox Code Playgroud)
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Run Code Online (Sandbox Code Playgroud)