我正在尝试访问这样的对象属性:
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)
但这使得代码非常冗长......所以有人知道是否有更简单的方法来做我想做的事情?谢谢。
通常的答案是&&运营商:
var v1 = scope1.b && scope1.b.value || 0;
Run Code Online (Sandbox Code Playgroud)
......因为喜欢||,&&是好奇地强大:&&评估左边的操作数,如果它的falsey,采用的是falsey价值作为其结果; 如果左侧操作数的值为真,则&&评估右侧操作数并将该值作为其结果。
所以如果scope1.b是undefined:
// 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); // 42Run Code Online (Sandbox Code Playgroud)
该实现不支持括号表示法,只支持点表示法,但是resolve(obj, "foo.0.bar.42", 0)如果您有需要的数字索引,您可以自由编写,因为它不受标准 JavaScript 解析规则的约束。(或者将其扩展到支持[]不会那么难。)