默认情况下,JavaScript简单对象覆盖

时间:2018-07-12 09:24:25

标签: javascript performance

bsd

我有一个简单的对象,如果对象中某些属性不存在,我想用另一个对象覆盖它,它应该取自默认的预设对象,可能是深层嵌套的

这是默认设置对象的示例

defaults = {
   name : 'Joe',
   options : {
      color : 'green',
      dates : {
         from : new Date,
         to   : new Date,
      }
   }
}

这里是提供的对象

settings = {
   name : 'David',
   options : {
      color : 'purple'
   }
}

这是预期的结果,两者之间的结合...

final = {
   name : 'David',
   options : {
      color : 'purple',
      dates : {
         from : new Date,
         to   : new Date,
      }
   }
}

是否有一种无需使用任何外部库即可实现此目标的简单方法?我尝试了一些方法(JSON.stringify / parse /遍历对象/等...),但无法获得干净的解决方案...希望有一个

任何帮助将不胜感激...

4 个答案:

答案 0 :(得分:2)

使用此$.extend(true, {}, defaults,settings)。注意json变量的顺序。在这种情况下,如果这两个变量具有相同的属性,settings将覆盖defaults

如果您正在寻找纯JS答案。这是代码。

function extend(a, b){
    for (var key in b) {
        if (b.hasOwnProperty(key))
            a[key] = b[key];
            return a;
        }
    }
}
console.log(extend(defaults,settings));

答案 1 :(得分:2)

这是我的贡献。

  

请注意,由于对象的shallowdeep复制的性质,代码很长。

使用Object.assign(defaults, settings)将合并您的对象,但是您的date键将对对象执行浅复制,因此将被删除。

下面,我使用了一个名为How to deep merge instead of shallow merge?的用户在jhildenbiddle上找到的摘要,该摘要执行对象的deep合并,并且是immutable(doesn' t编辑原始数组。


let defaults = {
  name: 'Joe',
  options: {
    color: 'green',
    dates: {
      from: new Date(),
      to: new Date(),
    }
  }
};

let settings = {
  name: 'David',
  options: {
    color: 'purple'
  }
};

function mergeDeep(...objects) {
  const isObject = obj => obj && typeof obj === 'object';

  return objects.reduce((prev, obj) => {
    Object.keys(obj).forEach(key => {
      const pVal = prev[key];
      const oVal = obj[key];

      if (Array.isArray(pVal) && Array.isArray(oVal)) {
        prev[key] = pVal.concat(...oVal);
      } else if (isObject(pVal) && isObject(oVal)) {
        prev[key] = mergeDeep(pVal, oVal);
      } else {
        prev[key] = oVal;
      }
    });

    return prev;
  }, {});
}

let final = mergeDeep(defaults, settings);

console.log(final);

答案 2 :(得分:1)

如果更改了默认值,则可以手动设置每个值。

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Repeater {
        model: rectlist
        delegate: Rectangle{
            x: modelData.rect.x
            y: modelData.rect.y
            width: modelData.rect.width
            height: modelData.rect.height
            color: modelData.color
            Text{
                anchors.centerIn: parent
                text: modelData.text
            }
        }
    }
}

这可能最有效:

final = {
      name : settings.name ? settings.name : "Joe",
      options {
        color: settings.color ? settings.color : "green",
        dates: {
          from : settings.dates.from ? settings.dates.from : new Date,
          to: settings.dates.to ? settings.dates.to : new Date
        }
      }
    }

答案 3 :(得分:0)

您可以看看Object.assign

final = Object.assign(defaults, settings)