Javascript获取对象属性和子属性

时间:2014-12-13 13:05:04

标签: 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

明显的||经营者没有给我我想要的东西。我知道我可以做以下事情

var vv2 = (scope1 && scope1.b ? scope1.b.value : 0);

但这会使代码变得非常冗长......所以任何人都知道有没有更简单的方法来做我想做的事情?感谢。

1 个答案:

答案 0 :(得分:4)

通常的答案是&&运算符:

var v1 = scope1.b && scope1.b.value || 0;

...因为与||一样,&&curiously powerful&&评估左侧操作数,如果它是假的,则采用该假名价值作为结果;如果左侧操作数值为真,则&&计算右侧操作数并将该值作为结果。

如果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

...但如果scope.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

(回想一下," falsey"值为undefinednull0""NaN,当然,false;以及" truthy"值都是其他值。)

示例:



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>
&#13;
&#13;
&#13;


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

&#13;
&#13;
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
&#13;
<!-- 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>
&#13;
&#13;
&#13;

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