JS检查深层对象属性的存在

我试图find一个优雅的方式来检查是否存在一个对象的某些深层的属性。 所以几乎试图避免对未定义的巨大的保护性检查。

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

我在想的是一个便利function

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

有任何想法吗? 为了方便,解决scheme使用下划线库 。

有几种可能性:

试着抓

 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

 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 

function替代 – 请参阅@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'); 

试试这个下划线混合来查找一个path的variables。 它需要一个对象,string和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`