通常的答案是&&
操作:
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