的Javascript获取对象的属性和子属性
问题描述:
我试图访问一个对象的属性是这样的:的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
apparentl的||操作员不给我我想要的。我知道我可以做以下代替
var vv2 = (scope1 && scope1.b ? scope1.b.value : 0);
但是这使得代码确实冗长的...所以任何人都知道,如果有更简单的方法做我想做的事?谢谢。
答
通常的答案是&&
操作:
var v1 = scope1.b && scope1.b.value || 0;
...因为喜欢||
,&&
是curiously powerful:&&
评估左侧操作数,如果它的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
...但如果scope.b
就像是一个对象引用一个truthy值:
// 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
(回想一下, “falsey” 值是undefined
,null
,0
,""
,NaN
,当然还有false
;“truthy”值a重新所有其他)
例:
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
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
我不推荐它,但你可以写一个函数为这个来处理任意深度:
function resolve(obj, path, defValue) {
var rv = path.split(".").reduce(function(o, p) {
return o && o[p];
}, obj);
return rv || defValue;
}
var scope1;
scope1 = {a: "foo"};
snippet.log(resolve(scope1, "b.value", 0)); // 0
scope1 = {a: "foo", b: {}};
snippet.log(resolve(scope1, "b.value", 0)); // 0
scope1 = {a: "foo", b: {value: 42}};
snippet.log(resolve(scope1, "b.value", 0)); // 42
scope1 = {a: "foo", b: {}};
snippet.log(resolve(scope1, "b.baz.boz.value", 0)); // 0
scope1 = {a: "foo", b: {baz: {boz: {value: 67}}}};
snippet.log(resolve(scope1, "b.baz.boz.value", 0)); // 67
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
即实现不支持括号符号,只是点符号,但你可以自由地写resolve(obj, "foo.0.bar.42", 0)
如果你有你需要的数字指标,因为它不符合标准的JavaScript解析规则。 (或者将其扩展到支持[]
就不会那么难)。
明白了!这绝对有帮助!所以&&是最好的(或最短的代码),我们可以用JavaScript做对吗? – 2014-12-14 17:38:07
@ChandlerLee:除非你想为它编写一个函数,并且执行'var v1 = foo(scope1,“b.value”,0);',这可能是过量的。 :-)我增加了一个这样做的例子。最后几个例子* *短于'var v1 = scope1.b && scope1.b.baz && scope1.b.baz.boz && scope1.b.baz.boz.value || 0;'会... – 2014-12-14 17:49:35