我试图在对象中深入分配一个值。例如:
const errors = {}
if(errorOnSpecificField) {
// TypeError: Cannot read property 'subSubCategory' of undefined(…)
errors.subCategory.subSubCategory.fieldWithError = 'Error Message'
}
现在,没有lodash,我可以做:
const errors = {}
if(errorOnSpecificField) {
errors.subCategory = errors.SubCategory || {}
errors.subCategory.subSubCategory = errors.SubCategory.subSubCategory || {}
errors.subCategory.subSubCategory.fieldWithError = 'Error Message'
}
使用lodash,我可以做到这一点:
const errors = {}
if(errorOnSpecificField) {
_.set(errors, 'subCategory.subSubCategory.fieldWithError', 'Error Message');
}
我试图避免使用第三方库。是否有一个更优雅的解决方案,尤其是现在ES2015的对象破坏了。逆操作很容易:
let {subCategory : {subSubCategory: {fieldWithError}}} = errors
什么是深层对象分配的优雅解决方案?谢谢!
这是一种安全分配给深度对象的相当可读的方法:
(((errors||{}).subCategory||{}).subSubCategory||{}).fieldWithError = 'Error Message'
errors.subCategory.subSubCategory
如果尚不存在。
简短的答案,不,没有编写方法的情况下没有干净的方法(tbh您可以在不导入整个库的情况下使用lodash的方法)
...但是...
警告这仅是为了娱乐。请勿在生产中尝试此操作(REQ ES6)。
Object.prototype.chainSet = function() {
let handler = {
get (target, name) {
if (!(name in target)) {
target[name] = new Proxy({}, handler)
}
return target[name]
}
}
return new Proxy(this, handler)
}
使用:
let a = {}
a.chainSet().foo.bar.baz = 1
a.foo.bar.baz // => 1
object.Assign()在您的要求方面工作正常。
let errors = { otherField: "value" };
let newobj = {subCategory : {subSubCategory: {fieldWithError: "Error goes here"}}};
Object.assign(errors, newobj);
这产生:
{
otherField:'value',
subCategory: {
subSubCategory: {
fieldWithError:'Error goes here'
}
}
}
您可以尝试以下类似:
function ErrorRegistry(obj)
{
this.errors = obj || {};
this.addError = function(k, msg)
{
var keys = k.split('.');
var o = this.errors;
for(var i = 0, l = keys.length, last = l-1; i<l; i++)
{
if(typeof o[keys[i]] === 'undefined')
o[keys[i]] = {};
if(i == last)
o[keys[i]] = msg;
else
o = o[keys[i]];
}
};
}
var errors = {'subCategory1':{'fieldWithError1':'Error1'}};
var errorRegistry = new ErrorRegistry(errors);
errorRegistry.addError('subCategory1.fieldWithError2', "Error2");
errorRegistry.addError('subCategory1.subSubCategory1.fieldWithError3', "Error3");
errorRegistry.addError('subCategory1.subSubCategory2.fieldWithError4', "Error4");
errors = errorRegistry.errors;
console.log(errors);