1. ホーム
  2. javascript

[解決済み] JavaScript、ネストされたオブジェクトのプロパティがNULL/未定義であることをチェックするエレガントな方法 [重複] (英語)

2022-08-12 18:14:45

質問

時々発生する問題ですが、例えば次のようなオブジェクトがあります。 user = {} というオブジェクトがあり、アプリを使用しているうちに、このオブジェクトに値が入るようになります。たとえば、AJAX 呼び出しなどの後に、次のようにします。

user.loc = {
    lat: 50,
    long: 9
}

別の場所で user.loc.lat が存在するかどうかを調べたいのです。

if (user.loc.lat) {
    // do something
}

存在しない場合は、エラーになります。もし user.loc.latundefined , 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段階のネストを想像してみてください)。 それは if(user.loc.lat) を返すだけでなく false もし user.locundefined も同様です。

このような状況を確認するための理想的な方法は何でしょうか?

どのように解決するのですか?

このようなユーティリティ関数を使用することができます。

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')) ...