私が時々持っている「問題」は、私がオブジェクトを持っているということです。 user = {}
そしてアプリを使用する過程で、これが読み込まれます。 AJAX呼び出しまたは何かをした後、どこかで言ってみましょう。
user.loc = {
lat: 50,
long: 9
}
別の場所で、user.loc.lat
が存在するかどうかを確認します。
if (user.loc.lat) {
// do something
}
存在しない場合、エラーが発生します。 user.loc.lat
がundefined
の場合、もちろんuser.loc
もundefined
です。
"Cannot read property 'lat' of null" - Dev Tools error
つまり、次のように確認する必要があります。
if (user.loc) {
if (user.loc.lat) {
// do something
}
}
または
if (user.loc && user.loc.lat) {
// do something
}
これはあまりきれいではなく、オブジェクトが大きくなればなるほど悪化します-明らかに(10レベルのネストを想像してください)。 user.loc
がfalse
である場合、if(user.loc.lat)
がundefined
を返すだけではないということはありがたいことです。
このような状況をチェックする理想的な方法は何ですか?
次のようなユーティリティ関数を使用できます。
get = function(obj, key) {
return key.split(".").reduce(function(o, x) {
return (typeof o == "undefined" || o === null) ? o : o[x];
}, obj);
}
使用法:
get(user, 'loc.lat') // 50
get(user, 'loc.foo.bar') // undefined
または、値を取得せずに、プロパティが存在するかどうかのみを確認するには:
has = function(obj, key) {
return key.split(".").every(function(x) {
if(typeof obj != "object" || obj === null || ! x in obj)
return false;
obj = obj[x];
return true;
});
}
if(has(user, 'loc.lat')) ...
さて、javascriptにはtry-catchがあります。実際に何をする必要があるか(つまり、else
の場合、undefined
ステートメントはどのように見えるか)に応じて、それが望みどおりになる場合があります。
例:
try {
user.loc.lat.doSomething();
} catch(error) {
//report
}
遅延and
を使用してチェックを結合できます。
if(user.loc && user.loc.lat) { ...
または、CoffeeScriptを使用して記述します
user.loc?.lat ...
loc
プロパティのチェックを実行し、空のオブジェクトから保護します。
これを試してくださいif(user && user.loc && user.loc.lat) {...}
typeof を使用して、nullおよび未定義の値を確認できます。
.loc
の値がfalse
の場合、試すことができます
if(user && user.loc && typeof(user.loc)!=="undefined"){...}
あなたが見ているよりも巨大なネストされたオブジェクトを持っている場合
Source .
function checkNested(obj /*, level1, level2, ... levelN*/) {
var args = Array.prototype.slice.call(arguments),
obj = args.shift();
for (var i = 0; i < args.length; i++) {
if (!obj.hasOwnProperty(args[i])) {
return false;
}
obj = obj[args[i]];
}
return true;
}
var test = {level1:{level2:{level3:'level3'}} };
checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false
更新:試す lodash.get