这个递归 JavaScript 函数有什么问题? [英] What am I doing wrong with this recursive JavaScript function?

查看:42
本文介绍了这个递归 JavaScript 函数有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是整个页面:

<头><script type="text/javascript" src="/jquery.js"></script><script type="text/javascript" src="/json2.js"></script><script type="text/javascript">函数构建列表(点){如果(!点)返回 [];儿童 = [];lis = point.children('li');for (index = 0; index < lis.length; index++) {id = $(lis[index]).attr('id');零件 = id.split('-');title = $(lis[index]).children('div').text();新对象 = {编号:零件[1],mtype:零件[0],标签:标题}ol = $(lis[index]).children('ol');//if (ol.length == 1) {//newObj['childobjects'] = buildList(ol);//}children.push(jQuery.extend(true, {}, newObj));}返回儿童;}$(函数(){obj = buildList( $('#menu-top') );警报( JSON.stringify(obj) );});<身体><ol id="menu-top" class="sortable ui-sortable"><li id="entry-16608"><div>测试项目1</div><ol><li id="entry-16607" "><div>新闻、链接和随机想法</div></ol><li id="entry-16609"><div>数据保留授权如何可能导致美国事实上的审查</div><li id="entry-16579"><div>Git 备忘单</div></ol></html>

当我注释掉递归调用时,我的 JSON 如下所示:

<预><代码>[{"id":"16608","mtype":"条目","label":"测试项目 1"},{"id":"16609","mtype":"条目","label":"数据保留授权将如何导致美国事实上的审查"},{"id":"16579","mtype":"条目","label":"Git 备忘单"}]

当我取消注释代码时,JSON 如下所示:

<预><代码>[{"id":"16607","mtype":"条目","label":"新闻、链接和随机想法"},{"id":"16607","mtype":"条目","label":"新闻、链接和随机想法"}]

我猜这是我对 JavaScript 如何处理作用域和递归的更精细细节的无知导致的结果,但我不知道在这里做什么.

解决方案

是的,这是一个范围问题.您忘记将 var 放在 all 变量的前面.这使变量成为全局变量,这意味着每个函数调用都可以访问相同的变量(并覆盖它们).

查看固定版本:http://jsfiddle.net/fkling/uYXYh/

您可以通过使用更多 jQuery 方法来进一步改进代码:

function buildList(point) {如果 (!point) 返回 [];var 孩子 = [];point.children('li').each(function() {var 部分 = this.id.split('-');var newObj = {编号:零件[1],mtype:零件[0],标签:$(this).children('div').text()};var $ol = $(this).children('ol');如果($ol.length == 1){newObj['childobjects'] = buildList($ol);}children.push(jQuery.extend(true, {}, newObj));//不知道你为什么//这样做而不是//children.push(newObj)});返回儿童;}

演示

Here is the entire page:

<html>
<head>
        <script type="text/javascript" src="/jquery.js"></script>
        <script type="text/javascript" src="/json2.js"></script>
        <script type="text/javascript">
                function buildList(point) {
                        if ( !point )
                                return [];
                        children = [];
                        lis = point.children('li');
                        for (index = 0; index < lis.length; index++) {
                                id = $(lis[index]).attr('id');
                                parts = id.split('-');
                                title = $(lis[index]).children('div').text();
                                newObj = {
                                        id: parts[1],
                                        mtype: parts[0],
                                        label: title
                                }
                                ol = $(lis[index]).children('ol');
                               // if (ol.length == 1) {
                               //         newObj['childobjects'] = buildList(ol);
                               // }
                                children.push(jQuery.extend(true, {}, newObj));
                        }
                        return children;
                }
                $(function() {
                        obj = buildList( $('#menu-top') );
                        alert( JSON.stringify(obj) );
                });
        </script>
</head>
<body>
<ol id="menu-top" class="sortable ui-sortable">
        <li id="entry-16608">
                <div>Test item 1</div>
                <ol>
                        <li id="entry-16607" ">
                                <div>News, links and random thoughts</div>
                        </li>
                </ol>
        </li>
        <li id="entry-16609">
                <div>How a data retention mandate will likely lead to de facto censorship in the US</div>
        </li>
        <li id="entry-16579">
                <div>Git cheat sheet</div>
        </li>
</ol>
</body>
</html>

When I comment out the recursive call, my JSON looks like this:

[
   {
      "id":"16608",
      "mtype":"entry",
      "label":"Test item 1"
   },
   {
      "id":"16609",
      "mtype":"entry",
      "label":"How a data retention mandate will likely lead to de facto censorship in the US"
   },
   {
      "id":"16579",
      "mtype":"entry",
      "label":"Git cheat sheet"
   }
]

When I uncomment the code, the JSON looks like this:

[
   {
      "id":"16607",
      "mtype":"entry",
      "label":"News, links and random thoughts"
   },
   {
      "id":"16607",
      "mtype":"entry",
      "label":"News, links and random thoughts"
   }
]

I'm guessing this is the result of ignorance on my part about the finer details of how JavaScript handles scoping and recursion, but I'm at a loss as to what to do here.

解决方案

Yes, it is a scope problem. You forgot to put var in front of all variables. This makes the variables global, meaning each function call has access to the same variables (and is overwriting them).

See the fixed version: http://jsfiddle.net/fkling/uYXYh/

You could further improve the code by making use of more jQuery methods:

function buildList(point) {
    if (!point) return [];
    var children = [];
    point.children('li').each(function() {
        var parts = this.id.split('-');
        var newObj = {
            id: parts[1],
            mtype: parts[0],
            label: $(this).children('div').text()
        };
        var $ol = $(this).children('ol');
        if ($ol.length == 1) {
            newObj['childobjects'] = buildList($ol);
        }
        children.push(jQuery.extend(true, {}, newObj)); // not sure why you are
                                                        // doing this instead of
                                                        // children.push(newObj)
    });
    return children;
}

DEMO

这篇关于这个递归 JavaScript 函数有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆