Javascript递归不停止

时间:2013-03-13 12:44:25

标签: javascript recursion

function alertJson(obj){  
    if (obj === undefined) return 'undefined\n';
    if (obj === null) return 'null\n';
    for (var k in obj){     
       alert(obj[k]);
       alertJson(obj[k]);   
    }

}

alertJson({
    a: {
        complicatedly: {
            nested: ['object']
        }
    }
});

我有两个问题......

  1. 为什么警报会在第四次警报后继续进行?
  2. 为什么它会为前两个项目带来第一个[object Object],然后为其他两个项目带来object

5 个答案:

答案 0 :(得分:2)

  1. 因为它是一个无限循环,因为它在字符串"o"上运行相同的操作,所以你真的需要在调用alertJson之前检查类型

  2. 因为当你toString()一个对象时它会返回[object Object],而对象本身就是字符串对象。

  3. <强>码

    function alertJson(obj) {
        //if (obj === undefined) return 'undefined\n';
        //if (obj === null) return 'null\n';
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                var val = obj[prop];
                console.log(val);
                if (val && typeof val === "object") {
                    alertJson(val);
                }
            }
        }
    }
    

    Running example

    或者您可以使用JSON.stringify(obj)

答案 1 :(得分:2)

我想你想打电话

alert(k);

而不是

alert(obj[k]);

使用alert(k)应该会给你: “a”&gt; “复杂地”&gt; “嵌套”&gt; 0

当您调用alertJson传入字符串时会导致递归。发生这种情况时,您遍历字符串,并使用每个字符调用alertJson(作为1个字符串)。

这个小提琴应该更接近你的期望:http://jsfiddle.net/9ZKvf/

答案 2 :(得分:2)

  

为什么警报会在第四次警报后继续进行?

因为您在字符串alertJson上调用'object'。然后,for循环将遍历字符串的每个字符,然后在每个字符上调用alertJson。因此,它将再次调用alertJson('o')alertJson('o')(字符串的第一个(也是唯一的)字符),依此类推,因为您没有字符串的退出条件。

  

为什么它会为前两个项目带来第一个[object Object],然后再为其他两个项目提供对象。

对象的默认字符串表示形式为[object Object]。数组的一个是它们元素的串联,由于数组只有一个元素,因此输出为object。字符串'object'显然会产生输出object

答案 3 :(得分:1)

回答你的第二个问题:

当变量obj[k]警报函数调用.toString()时:

var a = {};
console.log(a.toString()) // "[object Object]"
var a = [];
console.log(a.toString()) // ""
var a = ["1", "2", "3"];
console.log(a.toString()) // "1,2,3"

答案 4 :(得分:0)

我认为Felix Kling非常清楚地回答了你的问题。无论如何,这里是您的代码的更新版本。

function alertJson(obj){  
    for (var k in obj){
       if(!obj.hasOwnProperty(k))continue;
        alert(k+' : '+obj[k].toString());
        if(typeof obj[k]=='object'){alertJson(obj[k]);}
    }

}

alertJson({
    a: {
        complicatedly: {
            nested: ['object']
        }
    }
});

如果对象没有自己的属性,它没有从原型继承,那么我们不需要该值,所以我们跳过它并循环到下一个属性。继续;告诉循环继续而不读取循环中的其余语句

if(!obj.hasOwnProperty(k))continue;

我们不希望它一次一个字符循环遍历字符串对象

if(typeof obj[k]=='object'){alertJson(obj[k]);}