ES6(ES2015/JavaScript.next/Harmony)には、?.
in CoffeeScriptなどのnull
- safeプロパティアクセス(null伝播/存在)演算子がありますか?または、ES7で計画されていますか?
var aThing = getSomething()
...
aThing = possiblyNull?.thing
これは大体次のようになります。
if (possiblyNull != null) aThing = possiblyNull.thing
理想的には、undefined
がaThing
である場合、ソリューションはpossiblyNull
に(null
でさえ)割り当てるべきではありません。
現在それを実現する機能は、現在ステージ1です:オプションのチェーン。
https://github.com/tc39/proposal-optional-chaining
今日使用したい場合は、それを実現するBabelプラグインがあります。
https://github.com/davidyaha/ecmascript-optionals-proposal
Update(2017-08-01):公式プラグインを使用する場合は、新しいトランスフォームでBabel 7のアルファビルドを試すことができます。 マイレージは異なる場合があります
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
それは?ほど素敵ではありません。演算子ですが、同様の結果を得るには、次のようにします。
user && user.address && user.address.postcode
null
とundefined
は両方ともfalsy値( このリファレンスを参照 )であるため、&&
演算子の後のプロパティは、先行してnullまたは未定義ではありません。
または、次のような関数を作成することもできます。
function _try(func, fallbackValue) {
try {
var value = func();
return (value === null || value === undefined) ? fallbackValue : value;
} catch (e) {
return fallbackValue;
}
}
使用法:
_try(() => user.address.postcode) // return postcode or undefined
または、代替値で:
_try(() => user.address.postcode, "none") // return postcode or a custom string
いいえ。JavaScriptで lodash#get などを使用できます。
安全な資産アクセスのためのバニラ代替
(((a.b || {}).c || {}).d || {}).e
最も簡潔な条件付き割り当てはおそらくこれでしょう
try { b = a.b.c.d.e } catch(e) {}
リストを見てみると、 here 、現在、Ecmascriptに安全なトラバーサルを追加する提案はありません。したがって、これを行うための素晴らしい方法がないだけでなく、近い将来に追加されることはありません。
これはJavaScriptの質問であることは知っていますが、Rubyは要求されたすべての方法でこれを処理していると思うので、関連する参照ポイントだと思います。
.&
、try
、および&&には長所と潜在的な落とし穴があります。ここでこれらのオプションの素晴らしい概要: http://mitrev.net/Ruby/2015/11/13/the-operator-in-Ruby/
TLDR; Rubyistsの結論は、Dig
のほうが見やすく、valueまたはnull
が割り当てられるという強力な保証の両方であるということです。
TypeScriptの簡単な実装を次に示します。
export function Dig(target: any, ...keys: Array<string>): any {
let digged = target
for (const key of keys) {
if (typeof digged === 'undefined') {
return undefined // can also return null or a default value
}
if (typeof key === 'function') {
digged = key(digged)
} else {
digged = digged[key]
}
}
return digged
}
これは、ネストの深さに使用でき、関数を処理します。
a = Dig(b, 'c', 'd', 'e');
foo = () => ({});
bar = Dig(a, foo, 'b', 'c')
前の回答で示したように、try
アプローチは、JSで読むのと同じくらいいいです。また、この実装の欠点の1つであるループを必要としません。
安全なディープgetメソッドは、underscore.jsに自然に適合しているように見えますが、問題は文字列プログラミングを回避することです。文字列プログラミングを回避するために@Felipeの回答を変更します(または少なくともEdgeケースを呼び出し元にプッシュバックします):
function safeGet(obj, props) {
return (props.length==1) ? obj[keys[0]] :safeGet(obj[props[0]], props.slice(1))
}
例:
var test = {
a: {
b: 'b property value',
c: { }
}
}
safeGet(test, ['a', 'b'])
safeGet(test, "a.b".split('.'))