javascript:以编程方式确定对象的结构

javascript:以编程方式确定对象的结构,javascript,Javascript,我正在构建javascript(nodejs)与远程服务的集成。该服务返回格式不一致的结果,在javascript中,我正在努力确定如何根据响应切换格式 两种格式如下所示,第一种是当父级有一个子级时,第二种是当父级有>1个子级时: var single = { "Parent" : { "name" : "foo" } } var multi = { "Parent" : [ { "name" : "foo" }, { "name" : "bar" } ] } 因此,当我尝试在js中解析结果,

我正在构建javascript(nodejs)与远程服务的集成。该服务返回格式不一致的结果,在javascript中,我正在努力确定如何根据响应切换格式

两种格式如下所示,第一种是当父级有一个子级时,第二种是当父级有>1个子级时:

var single = { "Parent" : { "name" : "foo" } }
var multi = { "Parent" : [ { "name" : "foo" }, { "name" : "bar" } ] }
因此,当我尝试在js中解析结果,访问“name”的子属性时,我得到了不一致的结果:

for (var i in single) {
    console.log("child name: " + single[i].name;
}

for (var i in multi.Parent) {
    console.log("child name: " + multi.Parent[i].name;
}
确定我得到的是单一结果还是多重结果的最佳方法是什么?我尝试了“typeof response”,希望为multi获得一个“Array”,但没有成功。该对象最初是作为字符串接收的,但使用
JSON.parse(responseString)

可以测试要定义的“name”属性

var single = { "Parent" : { "name" : "foo" } };
var multi = { "Parent" : [ { "name" : "foo" }, { "name" : "bar" } ] };

console.log(single.Parent.name == undefined); // True
console.log(multi.Parent.name == undefined);  // False
Cf:

您可以测试要定义的“name”属性

var single = { "Parent" : { "name" : "foo" } };
var multi = { "Parent" : [ { "name" : "foo" }, { "name" : "bar" } ] };

console.log(single.Parent.name == undefined); // True
console.log(multi.Parent.name == undefined);  // False

Cf:

您可能可以使用
构造函数
属性

>> single.Parent.constructor == Array
false
>> multi.Parent.constructor == Array
true

您可能会使用
构造函数
属性

>> single.Parent.constructor == Array
false
>> multi.Parent.constructor == Array
true

typeof response
将告诉您两者都是对象,因为数组是一个对象

您可以尝试获取multi.Parent.length,如果它是一个数组,它将为您提供一个数字;如果它是一个JSON对象,它将为您提供一个未定义的数字。所以

for (var i = 0; i < multi.Parent.length; i++){
    console.log("child name", multi.Parent[i].name)
}
for(变量i=0;i
响应类型
将告诉您两者都是对象,因为数组是一个对象

您可以尝试获取multi.Parent.length,如果它是一个数组,它将为您提供一个数字;如果它是一个JSON对象,它将为您提供一个未定义的数字。所以

for (var i = 0; i < multi.Parent.length; i++){
    console.log("child name", multi.Parent[i].name)
}
for(变量i=0;i
我看到您在这里执行的错误。首先,两个响应都是对象。它是
Parent
字段,是对象或列表,取决于结果的数量。你不应该这样做:

single[i].name
相反,你应该写:

single.Parent[i].name
因此,要检查您是否有单个或多个响应,您必须检查

if(response.Parent instanceof Array){}

注意使用
instanceof
而不是
typeof
。顺便说一句,使用JSON从文本构造对象没有问题。

我看到您在这里执行的错误。首先,两个响应都是对象。它是
Parent
字段,是对象或列表,取决于结果的数量。你不应该这样做:

single[i].name
相反,你应该写:

single.Parent[i].name
因此,要检查您是否有单个或多个响应,您必须检查

if(response.Parent instanceof Array){}
注意使用
instanceof
而不是
typeof
。顺便说一句,用JSON从文本构造对象没有问题。

最终代码:

// Using instanceof
if (response.Parent instanceof Array !== true) response.Parent = [response.Parent]
// More robust method, using .constructor:
if (response.Parent.constructor !== Array) response.Parent = [response.Parent]

// Continue with multi processing 
for (var i in response.Parent) {}
感谢所有反馈。

最终代码:

// Using instanceof
if (response.Parent instanceof Array !== true) response.Parent = [response.Parent]
// More robust method, using .constructor:
if (response.Parent.constructor !== Array) response.Parent = [response.Parent]

// Continue with multi processing 
for (var i in response.Parent) {}

感谢所有的反馈。

@yakxxx:是的,但最终:
x instanceof Object
将始终为真,除了常量,所以careful@EliasVan Ootegem在这种情况下,他可以对数组执行
x instanceof Array
,这对数组来说是正确的。@yakxxx:当然,但我的意思是,使用
instanceof
时必须小心:
switch(true){case x instanceof Array:return'Array';case x instanceof Object:return'Object';}
将按预期执行,但第一种情况是
x instanceof Object:return'Object',它不会。这是一件令人厌烦的事。在具有相当长的继承链和许多自定义对象构造函数的环境中,
instanceof
更容易出错对于我的用例来说,instanceof工作得很好,尽管我可以理解.constructor方法可能更具可移植性的原因。@yakxxx:是的,但最终:
x instanceof object
将始终为真,除了常数之外,一切都可以careful@EliasVan Ootegem在这种情况下,他可以对数组执行
x instanceof Array
,这对数组来说是正确的。@yakxxx:当然,但我的意思是,在使用
instanceof
时必须小心:
开关(true){case x instanceof Array:return'Array';case x instanceof Object:return'Object';}
将按预期执行,但当第一种情况是
x instanceof Object:return'Object';
时,它不会。这是一件令人厌倦的事情。在一个继承链相当长,并且有许多自定义对象构造函数的环境中,
instanceof
对于我的用例来说更容易出错,instanceof工作得很好,尽管我可以使用e为什么.constructor方法可能更具可移植性。