javascript递归函数 求js高手解答,要实现一个根据路径获取json对象值的函数,有很多不明白的地方

function Run(json,path){
if(path.length<=1){
value=json[path[0]]; // 如果这里换成var value=json[path[0]]结果是undefined
}
else {
var temp;
temp=json[path[0]]; //这里为什么不能用 json=json[path[0]]
path.splice(0,1);
Run(temp,path);
//arguments.callee(temp,path);
}
return value;
}
var myjson={a:1,b:{c:{e:3},d:4}};
var mypath=['b','d','e'];
var test=Run(myjson,mypath);
alert(test);
这样一个简单函数耗了我3个小时,各种尝试都试了最后才实现结果,但怎么也想不通为什么,标注的两个地是卡住的地方,
1如果value换成局部变量,为什么返回是空,
2为什么json=json[path[0]],这么用会报错,一定要经过一个中间变量
3能不能说说引用具体是怎么回事,比如var a={b:1};b=a;b.b=2,为什么a.b也会跟着变,为什么a,b指向一个地址
最后路径写错了,是["b","c","e"],忘高手解答,满意所有分全部奉上

递归经常碰到的问题了。
出问题的地方是 Run(temp,path);
既然是递归的调用 而且这个函数本身 有 return 值 那么 你应该在
调用 Run(temp,path);的时候 接收他的返回值
应该写成 value = Run(temp,path);

1. 现在你可以设成 局部变量 var value 了。
之所以出现undefined就是因为
return value 这行代码 就执行了 1次 也就是 第一个执行 var test=Run(myjson,mypath);的时候
这个时候 value 变量还没有定义出来, value是在 最后一次执行 Run(temp,path);的时候才定义的,而需要把这个 返回出来 并接收 才有效。

2. json=json[path[0]],
这个地方 不会报错 你是写错了代码
你如果 把这个地方 写成 json=json[path[0]],
那么下面 Run(temp,path); 是不是也应该写成 Run(json,path);呢?
这样就不会报错。

3. 在javascript里 数组和 对象 都是属于 引用类型的, 这是为了 节省内存空间。
其实道理简单, var a = {b:1} 这个时候 a变量里面 存储的是 保存这个 对象的内存地址,
打个比方 这个对象是一个宝箱 他是隐藏在内存的, a变量里面是打开这个宝箱的钥匙和地图
那么 b=a的时候 只是 复制了 钥匙和地图, 宝箱还是一个, 所以这个时候 a 和b 是指同一个对象的。

最后代码 修改后是这样

function Run(json,path){
if(path.length<=1){
var value=json[path[0]]; // 如果这里换成var value=json[path[0]]结果是undefined
} else {
var temp;
json=json[path[0]]; //这里为什么不能用 json=json[path[0]]
path.splice(0,1);
value = Run(json,path);
//arguments.callee(temp,path);
}
return value;
}
var myjson={a:1,b:{c:{e:3},d:4}};
var mypath=['b','c','e'];
var test=Run(myjson,mypath);
alert(test);
温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-10-31
function Run(json,path){
var value;
if(path.length<=1){
value=json[path[0]]; // 如果这里换成var value=json[path[0]]结果是undefined
}
else {
json = json[path[0]]; //这里为什么不能用 json=json[path[0]]
path.splice(0,1);
value = Run(json,path);
}

return value;
}
======================
看一下你写的函数,参数mypath有两个以上元素,走else分支的时候value没有赋值,当然是undefined。本回答被网友采纳
第2个回答  2012-10-31
这个问题貌似用不到递归,楼主试下这个:
<script type="text/javascript">
var myjson={a:1,b:{c:{e:3},d:4}}, mypath=['b','c'];
function Run(json, path){
if (!(path instanceof Array && path.length > 0)){ return json; }
var i=0, p = path[i], o = json[p];
while(p && o){
i++; p = path[i];
if (!o[p]){ return o; } else { o = o[p]; }
}
return o;
}

alert(Run(myjson, mypath));
</script>
第3个回答  2012-10-31
1:value是局部变量那么它的作用域只存在于if(path.length){}中,外面是取不到的所以你的return肯定是undefined,局部变量是好习惯,避免全局污染,效率还比较高,这里你可以在function Run里先声明下,方法内就可以使用了。

2:梳理了你的逻辑,第一处注释和上面的问题是一样的,第二处注释json=json[path[0]]这个写法本身没有错误,这里应该存在书写上或修改后逻辑上的错误。

3:首先要明白对象是存在栈里面的,也就是直接存值,变量是地址赋值,也就是引用赋值(存在堆里面),这是javascript的规定用于复用达到节省内存开销的作用,类似于C指针的概念。如果你需要值赋值,那么请直接找关于javascript克隆的方法。

4:建议你还是了解下基础,多耐心些,有时候长期面对代码,脑袋会范木,缓缓心情,自然是水到渠成。
相似回答