Javascript 创建和定义JS对象的属性和子项目

Javascript 创建和定义JS对象的属性和子项目,javascript,object,Javascript,Object,我有一个变量x,它可能有或没有一些属性propA,我想影响一些子属性propA1,并在需要的时候创建propA,因此可以使用有效的代码 if ('propA' in x) { x.propA.propA1='0' } else { x.propA={'propA1' : 0} } 或者我可以用try..catch做一些事情,但实际上我有一些嵌套属性的长列表,我想要一些类似于 x.propA.propA1=0 如果x没有propA属性,而是使用{'propA1':0} 或者在一

我有一个变量x,它可能有或没有一些属性
propA
,我想影响一些子属性
propA1
,并在需要的时候创建propA,因此可以使用有效的代码

if ('propA' in x) {
    x.propA.propA1='0'
} else {
    x.propA={'propA1' : 0}
}
或者我可以用
try..catch
做一些事情,但实际上我有一些嵌套属性的长列表,我想要一些类似于

x.propA.propA1=0
如果x没有
propA
属性,而是使用
{'propA1':0}

或者在一个好的JS代码中,所有这些属性都应该从一开始就定义?或者我想

x.propA.propA1

返回
未定义的
,如果
propA
未定义,则不会引发错误,但我想这不是它的意图……

遗憾的是,在设置属性时,只有在获取属性时,才有新的可选链接操作符

您所做的已经是如何做到这一点的,尽管您可以只测试对象,而不是在
中使用
,这可能会或可能不会稍微更有效,但肯定更惯用:

if (x.propA) { // *** Change is on this line
    x.propA.propA1='0'
} else {
    x.propA={'propA1' : 0}
}
这是因为任何对象都是真实的,从对象读取不存在的属性会导致值
未定义
,这是错误的

如果愿意,您可以使用实用程序功能:

function setSub(obj, main, sub, value) {
    if (obj[main]) {
        obj[main][sub] = value;
    } else {
        obj[main] = {[sub]: value};
    }
    return obj;
}
在您的示例中使用它:

setSub(x, "propA", "propA1", 0);

另一种方法是每次创建一个新对象,这在遵循不可变编程准则时通常很有用,但会产生开销:

x.propA = {...x.propA, propA1: 0};
请注意,即使当
x.propA
不存在时,这种方法也有效,因为属性扩展表示法明确允许扩展
未定义的
null
——这样做不会向结果对象添加任何属性。因此,上面将从
x.propA
复制属性(如果存在),如果不存在则忽略它,并在结果中包含
propA:0
属性:

constx1={};
x1.propA={…x1.propA,propA1:0};
控制台日志(x1);
constx2={propA:{};
x2.propA={…x2.propA,propA1:0};
控制台日志(x2);
constx3={propA:{unrelated:“example”};
x3.propA={…x3.propA,propA1:0};
控制台日志(x3)
。作为控制台包装器{
最大高度:100%!重要;

}当
X={propA:null}
@misterjojojo时,
不起作用-因为OP的代码在这种情况下会抛出一个错误(因为
测试中的
是真的,然后他们会尝试在
null
上创建一个属性),我认为我们可以合理地假设他们不会这样做。不清楚你在问什么。您想知道哪种方法被认为是“最佳实践”吗?或者您是否正在寻求关于如何实现您提到的方法之一的帮助?如果('propA'在x中)
,那么使用
有什么不好的地方?我一直在寻找更简洁的方法,在这里,知道好的实践总是很好的