Javascript获取对象属性和子属性

Shi*_*Lee 1 javascript

我正在尝试访问这样的对象属性:

var scope1 = {a: {value: 25}};
var scope2 = undefined;

var v1 = scope1.b.value || 0;  // TypeError: Cannot read property 'value' of undefined
var v2 = scope2.b.value || 0;  // TypeError: Cannot read property 'value' of undefined
Run Code Online (Sandbox Code Playgroud)

显然是 || 接线员没有给我我想要的。我知道我可以执行以下操作

var vv2 = (scope1 && scope1.b ? scope1.b.value : 0);
Run Code Online (Sandbox Code Playgroud)

但这使得代码非常冗长......所以有人知道是否有更简单的方法来做我想做的事情?谢谢。

T.J*_*der 5

通常的答案是&&运营商:

var v1 = scope1.b && scope1.b.value || 0;
Run Code Online (Sandbox Code Playgroud)

......因为喜欢||&&好奇地强大&&评估左边的操作数,如果它的falsey,采用的是falsey价值作为其结果; 如果左侧操作数的值为真,则&&评估右侧操作数并将该值作为其结果。

所以如果scope1.bundefined

// We start with
scope1.b && scope1.b.value || 0
// which is
undefined && scope1.b.value || 0
// which is
undefined || 0
// which is
0
Run Code Online (Sandbox Code Playgroud)

...但是 ifscope.b是一个像对象引用这样的真实值:

// We start with
scope1.b && scope1.b.value || 0
// which is
scope1.b.value || 0
// which is
scope1.b.value // *IF* scope1.b.value is truthy, or
0              // If it isn't
Run Code Online (Sandbox Code Playgroud)

(回想一下,“falsey”值是undefined, null, 0, "", NaN,当然还有false; 和“truthy”值都是其他值。)

例子:

var v1 = scope1.b && scope1.b.value || 0;
Run Code Online (Sandbox Code Playgroud)
// We start with
scope1.b && scope1.b.value || 0
// which is
undefined && scope1.b.value || 0
// which is
undefined || 0
// which is
0
Run Code Online (Sandbox Code Playgroud)


我不推荐它,但是您可以为此编写一个处理任意深度的函数:

// We start with
scope1.b && scope1.b.value || 0
// which is
scope1.b.value || 0
// which is
scope1.b.value // *IF* scope1.b.value is truthy, or
0              // If it isn't
Run Code Online (Sandbox Code Playgroud)
var scope1;

scope1 = {a: "foo"};
snippet.log(scope1.b && scope1.b.value || 0); // 0

scope1 = {a: "foo", b: {}};
snippet.log(scope1.b && scope1.b.value || 0); // 0

scope1 = {a: "foo", b: {value: 42}};
snippet.log(scope1.b && scope1.b.value || 0); // 42
Run Code Online (Sandbox Code Playgroud)

该实现不支持括号表示法,只支持点表示法,但是resolve(obj, "foo.0.bar.42", 0)如果您有需要的数字索引,您可以自由编写,因为它不受标准 JavaScript 解析规则的约束。(或者将其扩展到支持[]不会那么难。)