我一直在尝试在缺少属性的情况下初始化对象,这与我们使用OR运算符对变量的处理方式类似:
var finalValue = myVariable || 'hello there'
我已经找到了很多有关使用Object.assign()方法执行此操作的答复:
finalObject = Object.assign({}, defaultObject, myObject)
不过,当涉及到带有嵌套数据的对象时,我仍然没有找到合适的解决方案。这是我想到的:
var arrayConstructor = [].constructor;
var objectConstructor = ({}).constructor;
var whatIsIt = function(object) {
if (object === null) {
return "null";
} else
if (object === undefined) {
return "undefined";
} else
if (object.constructor === arrayConstructor) {
return "array";
} else
if (object.constructor === objectConstructor) {
return "object";
} else {
return "normal variable";
}
}
var copyWithValidation = function(jsonObject, defaultValues) {
let defaultKeys = Object.keys(defaultValues);
let returnValue = Object.assign({}, defaultValues, jsonObject);
// Check for json object
defaultKeys.map((key) => {
switch (whatIsIt(defaultValues[key])) {
case 'object':
if (!jsonObject.hasOwnProperty(key)) {
jsonObject[key] = {};
}
returnValue[key] = copyWithValidation(jsonObject[key], defaultValues[key]);
break;
case 'array':
if (jsonObject.hasOwnProperty(key)) {
returnValue[key] = [...jsonObject[key]];
} else {
returnValue[key] = [...defaultValues[key]];
}
break;
default:
break;
}
});
return returnValue;
}
// My default object
var def1 = {
label1: '',
label2: '',
label3: '',
sublabels: {
label1: '',
label2: '',
label3: '',
},
sublabels2: {
label1: '',
label2: '',
label3: '',
label4: {
title: '',
subtitle: '',
},
},
sublabels3: {
label1: [],
label2: [],
label3: [],
},
}
// The object we want to initialize
var j1 = {
label1: 'hello1',
label2: 'hello2',
sublabels: {
label2: 'subhello2',
label3: 'subhello3',
},
sublabels3: {
label1: ['subhello1', 'subhello2', 'subhello3'],
label4: {
title: 'Hello there!',
subtitle: 'Hello there again',
},
},
}
// Let's run the script!
let p = copyWithValidation(j1, def1);
console.log(p);
整个想法是遍历对象,并且最初使用“ Object.assign({},defaultValues,jsonObject)”方法“复制”特定级别的属性。之后,我要检查是否存在对象或数组。
对于对象,我将{}设置为目标对象(如果属性不存在),然后在该对象内调用相同的copyWithValidation()方法;递归将覆盖所有级别。
在数组的情况下,我只是使用散布运算符。有趣的是,这甚至适用于作为数组元素的对象。
不确定是否有更有效的代码可以返回相同的结果。
对Aamir Afridi和Joaquin Keller的使用/组合脚本表示敬意。
答案 0 :(得分:0)
您可以使用递归来定位嵌套。要注意的是,模板不包含sublabels3.label4属性,而数据对象却包含sublabels3.label4属性。该代码配置为在发生这种情况时添加缺少的属性。
var def1 = {
label1: '',
label2: '',
label3: '',
sublabels: {
label1: '',
label2: '',
label3: '',
},
sublabels2: {
label1: '',
label2: '',
label3: '',
label4: {
title: '',
subtitle: '',
},
},
sublabels3: {
label1: [],
label2: [],
label3: []
},
}
// The object we want to initialize
var j1 = {
label1: 'hello1',
label2: 'hello2',
sublabels: {
label2: 'subhello2',
label3: 'subhello3',
},
sublabels3: {
label1: ['subhello1', 'subhello2', 'subhello3'],
label4: {
title: 'Hello there!',
subtitle: 'Hello there again',
},
},
}
function initializer(data,template) {
return Object.entries(data).reduce((initialized, [key, value]) =>{
if(typeof value === "object" && !Array.isArray(value)){
initialized[key] = initializer(value, initialized[key] || {})
return initialized
} else {
initialized[key] = value;
return initialized
}
},template)
}
console.log(initializer(j1,def1))