[英]Javascript: Get a reference from JSON object with traverse
我需要从JSON对象获取引用,代码如下:
var Tree = { data: { 0: { pk: 1, }, 1: { pk: 2, }, 2: { pk: 3, children: { 0: { pk: 11, }, 1: { pk: 22, }, 2: { pk: 33, }, }, }, }, traverse: function(data, pk) { for (i in data) { // console.log(data[i]); if(data[i].pk && data[i].pk == pk) return data[i]; if (typeof(data[i].children) == 'object') this.traverse(data[i].children, pk); }; }, }
遍历顶层项目时,该代码非常有效:
>>> Tree.traverse(Tree.data, 1); Object {pk=1}
但是在获取子元素时坏了:
>>> Tree.traverse(Tree.data, 22); undefined
当您取消注释“ // console.log(data [i]);”时,为什么会出现这种行为我感到非常奇怪。 行,您将看到对象已获得但未返回。
有什么想法吗?
你没有把return
前this.traverse(data[i].children, pk);
。
编辑:
var Tree = {
data: {
0: {
pk: 1,
},
1: {
pk: 2,
},
2: {
pk: 3,
children: {
0: {
pk: 11,
},
1: {
pk: 22,
},
2: {
pk: 33,
},
},
},
},
traverse: function(data, pk) {
for (var i in data) {
// console.log(data[i]);
if(data[i].pk && data[i].pk == pk)
return data[i];
if (typeof(data[i].children) == 'object') {
var retVal = this.traverse(data[i].children, pk);
if (typeof retVal!='undefined') {//here was the logical problem,there might be more than one
//object, we can't return the result of traversing first one.
//So we will check, if no return, we go on searching
return retVal;
}
}
};
},
};
alert(Tree.traverse(Tree.data, 1).pk);
alert(Tree.traverse(Tree.data, 22).pk);
在此处查看直播: http : //jsfiddle.net/rq4LK/
这是一个远景,但是您正在for
循环中创建全局变量。 尝试for(var i in data)
代替,然后报告。
在这种情况下不整的对象和你的物业设有一个按键(如3: ...
)在父Object
并不在存在字面children
子属性,它显然会返回undefined
,因为没有这样的该键的属性。
编辑:根据您的评论,这可能是函数范围的问题,因为您正在使用尾部递归来遍历具有多个层的对象。 因此,请像在需要动态引用的任何javascript语言构造中所做的那样,尝试将当前对象引用置于函数范围之外:
var current = null , match = null ;
function traverse() {
var data = arguments[0] ;
var pk = arguments[1] ;
for(var i in data) {
current = data[i] ; /* DEBUG */console.log( current.toSource() ) ; //!! Object.prototype.toSource() requires a W3 compatible browser (like FF)
if(current.pk !== undefined && current.pk === pk) return current ;
else if( typeof current.children === "object") traverse(current.children, pk);
}
}
match = traverse(data,pk) ;
编辑2:我的逻辑有缺陷。 尝试以下方法:
var match = null ;
function traverse() {
var data = arguments[0] ;
var pk = arguments[1] ;
var current = null ;
for(var i in data) {
current = data[i] ; /* DEBUG */console.log( current.toSource() ) ; //!! Object.prototype.toSource() requires a W3 compatible browser (like FF)
if(current.pk !== undefined && current.pk === pk) match = current ; //!! if there is a match set the variable match to the current object
else if( typeof current.children === "object") traverse(current.children, pk); //!! else use recursion to test a child property if present
}
}
使用该方法,如果您的对象包含指定的属性,则match
不会为null
,而是包含匹配的对象或子对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.