【问题标题】:JS checking deep object property existence [duplicate]JS检查深层对象属性是否存在[重复]
【发布时间】:2013-11-28 23:23:23
【问题描述】:

我正在尝试寻找一种优雅的方法来检查对象中是否存在某些深层属性。所以实际上试图避免对未定义的例如可怕的保护性检查。

if ((typeof error !== 'undefined') && 
  (typeof error.responseJSON !== 'undefined') &&
  (typeof error.responseJSON.error) && 
  (typeof error.responseJSON.error.message)) {
      errorMessage = error.responseJSON.error.message;
}

我在想的是一个方便的功能,比如

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

有什么想法吗?为方便起见,解决方案可以使用underscore-library。

【问题讨论】:

  • 您可以通过将您的请求作为字符串传递给函数来做到这一点。该函数应该用“。”分割字符串。或其他东西,然后遍历每个段以查找每个值。不过,还有其他问题和很好的答案:stackoverflow.com/questions/8817394/…
  • 我在想是否有办法为对象而不是字符串处理这个?当然,我可以只 JSON.stringify 对象,但如果它直接处理对象,我会感觉好多了。
  • 如果你使用了一个对象,你需要创建你正在寻找的整个结构(这很庞大,甚至比到处都是&& 还要糟糕)。字符串可能看起来很奇怪,但它是最灵活和最紧凑的解决方案。另一种方法是传递一个数组,它只是预先拆分的字符串。然后迭代该向下钻取到目标对象。

标签: javascript undefined


【解决方案1】:

有几种可能:

试一试

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

失败:

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

&&

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

失败:

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

功能

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

失败:

// It's hard(er) to use

功能替代 - 参见@Olical 的评论

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

【讨论】:

    【解决方案2】:

    试试这个underscore mixin 来查找带有路径的变量。它需要一个对象和字符串以及 t

    _.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;
        }
    });
    

    现在调用你的例子:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 2020-05-08
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      相关资源
      最近更新 更多