我在Javascript上编写一个函数,需要解决JSON对象中的所有任何类型。
例如,
Typed= {
emails: [{email:'a@a.com'}, {email:'b@a.com'}, {email:'c@a.com'}, {email:'d@a.com'}]
};
是JSON中类型化数组的示例,因为数组中的每个元素都是email
而,
Anon= {
emails: ['a@a.com', 'b@a.com', 'c@a.com', 'd@a.com']
};
是一个JSON对象,其中电子邮件是一些匿名对象的集合。
我有什么办法可以在JQuery或Javascript中区分它们吗?
答案 0 :(得分:3)
最简单的解决方案是让JSON源只返回两种形式中的一种。然后你不必在你的客户端分支。
如果这不是一个选项,你可以使用JavaScript对布尔表达式的方便的懒惰评估来获取值:
var em = json.emails[0].email || json.emails[0];
该语句更喜欢对象数组版本,但使用数组字符串版本作为后备。
(编辑以回应以下澄清评论)
您可以确定JS对象在运行时具有的属性,如下所示:
function enumerate(targetObject){
var props = [];
for (var propName in targetObject ){
props.push(propName);
}
return props;
}
console.log(enumerate({foo:1, bar:'baz'}),join(',')); //"foo, bar"
然后,您可以根据您获得的属性调整逻辑。您还需要确保了解原型(特别是Object.hasOwnProperty
的作用和含义)。
答案 1 :(得分:1)
这个怎么样:
var istyped = function (a) {
if (typeof(a) !== 'object') {
return false;
}
var count = 0;
for (var key in a) {
count = count + 1;
}
return (count === 1);
}
我在这里假设您只想区分常规变量(这将是您的匿名变量)和内部只有一个键/值对的对象(这将是您的类型变量)。
要检查数组是否只包含类型变量,您只需使用该函数循环它。例如(在较新版本的JavaScript中):
Typed.emails.every(istyped) = true
Anon.emails.every(istyped) = false
答案 2 :(得分:1)
您可以使用Array iteration methods快速检查数组的所有(或某些)元素是否具有所需的类型:
Anon.emails.every(function(e) { return typeof e == "object" }) // false
Typed.emails.every(function(e) { return typeof e == "object" }) // true
或更通用的解决方案
typeCheck = function(type) {
return function() {
return typeof arguments[0] == type
}
}
Anon.emails.every(typeCheck("object")) // false
Typed.emails.every(typeCheck("object")) // true
(关于ancient browsers不支持迭代方法的强制性警告)
答案 3 :(得分:0)
为什么不先做地图:
emails = emails.map(function (email) {
if (typeof email.email === 'string')
return email.email;
});
这将使您的电子邮件数组成为一个只有字符串的数组。然后你可以像往常一样处理它。如果它是一个字符串数组,则没有任何副作用(email.email
将是未定义的。)
当我必须让一个客户端处理多个版本的API时,我会这样做。或者,你可以用另一种方式做地图:
emails = emails.map(function (email) {
if (typeof email === 'string')
return {email: email};
});
如果电子邮件阵列中的每个对象中都有其他信息,这样会更好。