用于检查属性是否存在的简写函数

你们能帮我做一个简写函数来判断对象属性是否存在吗? 在99%的情况下,我想用它来检查返回的json对象是否包含指定的属性。 请注意,无法保证必须定义任何父属性甚至json对象本身。

我正在以这种方式思考问题:

function propertyExists() { // property is something like data.property.property return typeof(data) !== "undefined" && typeof(data.property) !== "undefined" && typeof(data.property.property) !== "undefined"; } 

我不知道如何以动态方式编写它以检查所有父属性。 in-parameter也应该只是对“data.property.property”的引用,而不是字符串,所以我不知道如何在其中找到父属性。

这是我在项目中所处的函数,它告诉您是否定义了属性(包括其所有父属性,如果有的话):

 function isDefined(target, path) { if (typeof target != 'object' || target == null) { return false; } var parts = path.split('.'); while(parts.length) { var branch = parts.shift(); if (!(branch in target)) { return false; } target = target[branch]; } return true; } 

它应该像这样使用:

 var data = { foo: { bar: 42 } }; isDefined(data, "foo"); // true isDefined(data, "foo.bar"); // true isDefined(data, "notfoo"); // false isDefined(data, "foo.baz"); // false 

您可以轻松调整此值以返回值本身(或null )而不是true / false

更新:在阅读了关于这个问题的评论之后,我用Google搜索了Javascript in operator并用那个替换了typeof测试。 现在代码写成“它的意图是什么”。

允许JSON属性包含点,如{"ab": 42} ,这使得点串不适合对象的“深度引用”。

 isDefined({"ab": 42}, 'a.b') // false isDefined({"a": 42}, 'a.b') // TypeError 

因此,数组可能是参考或索引的更好选择

 function hasProperty(value, index) { if (index instanceof Array) { return index.length === 0 || (hasProperty(value, index[0]) && hasProperty(value[index[0]], index.slice(1))); } return value.hasOwnProperty(index); } 

它使用如下:

 hasProperty(42, []); // true hasProperty(42, ['a']); // false hasProperty(42, ['a']); // false hasProperty({a: 42}, 'a'); // true hasProperty({a: 42}, ['a']); // true hasProperty({a: 42}, ['a', 'b']); // false hasProperty({a: {b: 42}}, ['a', 'b']); // true hasProperty({"ab": 42}, ['a.b']); // true hasProperty([1,2,3], 2); // true hasProperty([1,2,3], 3); // false hasProperty({a: {b: [1,2,3]}}, ['a', 'b', 2]); // true 

请注意,由于使用了原型函数hasOwnPropertyhasProperty忽略原型中的属性。

我目前无法找到其他post,相当确定以下内容是正确的:

 function checkAccess(obj, path) { var path = path.split('.'); var prop; for (var i=0, iLen=path.length; i 

请注意,这应该适用于JSON,但如果涉及主机对象,则所有投注都会关闭,因为在这种情况下, typeof不能保证返回对象 (或任何内容)。 如果您需要测试主机对象,可能try..catch将是最强大的解决方案,除非您确信正在测试的对象将返回预期的结果。

 try { alert( o.foo.bar.baz); } catch(e) { alert( 'oops'); } 

如果你想使用单个参数,那么我将假设基础对象是一个全局属性:

 var checkAccess = (function(global) { return function (expr) { var path = expr.split('.'); var obj, prop; if (path.length) { obj = global[path.shift()]; for (var i=0, iLen=path.length; i 

编辑

请注意,上述内容仅意味着尝试访问路径不会返回错误,并不意味着它将返回一个值(可能是未定义的,null或其他内容)。