关于javascript:JS检查深层对象属性是否存在

JS checking deep object property existence

本问题已经有最佳答案,请猛点这里访问。

我试图找到一种优雅的方法来检查对象中是否存在某些深度属性。 因此,实际上试图避免对未定义的怪异保护性检查。

1
2
3
4
5
6
if ((typeof error !== 'undefined') &&
  (typeof error.responseJSON !== 'undefined') &&
  (typeof error.responseJSON.error) &&
  (typeof error.responseJSON.error.message)) {
      errorMessage = error.responseJSON.error.message;
}

我正在考虑的是一个方便功能

1
if (exists(error.responseJSON.error.message)) { ... }

有任何想法吗? 为方便起见,使用下划线库可以解决问题。


有几种可能性:

试着抓

1
2
3
try {
  errorMessage = error.responseJSON.error.message;
} catch(e) { /* ignore the error */}

失败:

1
2
3
Object.defineProperty(error, 'responseJSON', {
  get: function() { throw new Error('This will not be shown')
});

&安培;&安培;

1
errorMessage = error && error.responseJSON && error.responseJSON.error && error.responseJSON.error.message;

失败:

1
2
error.responseJSON = 0;
// errorMessage === 0 instead of undefined

功能

1
2
3
4
5
6
7
8
9
10
11
12
function getDeepProperty(obj,propstr) {
  var prop = propstr.split('.');
  for (var i=0; i<prop.length; i++) {
    if (typeof obj === 'object')
      obj = obj[prop[i]];
  }
  return obj;
}

errorMessage = getDeepProperty(error, 'responseJSON.error.message');

// you could put it all in a string, if the object is defined in the window scope

失败:

1
// It's hard(er) to use

功能替代 - 请参阅@Olical的评论

1
2
3
4
5
6
7
8
9
function getDeepProperty(obj) {
  for (var i=1; i<arguments.length; i++) {
    if (typeof obj === 'object')
      obj = obj[arguments[i]];
  }
  return obj;
}

errorMessage = getDeepProperty(error, 'responseJSON', 'error', 'message');

尝试使用下划线mixin查找带路径的变量。 它需要一个对象和字符串和t

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
_.mixin({
    lookup: function (obj, key) {
        var type = typeof key;
        if (type == 'string' || type =="number")
            key = ("" + key).replace(/\[(.*?)\]/, function (m, key) { //handle case where [1] may occur
                return '.' + key.replace(/["']/g,""); //strip quotes
            }).split('.');
        for (var i = 0, l = key.length; i < l; i++) {
            if (_.has(obj, key[i]))
                obj = obj[key[i]];
            else
                return undefined;
            }
        return obj;
    }
});

现在打电话给你的例子:

1
_.lookup(error, 'responseJSON.error.message') // returns responseJSON.error.message if it exists otherwise `undefined`