javascript - 递归函数中的 Array.prototype.reduce 产生意外结果

标签 javascript arrays dom recursion ecmascript-5

我正在尝试编写一个函数将数组转换为 DocumentFragment。数组中的每一项都将成为一个 HTMLElement。它的标签名称将是数组项的类名*,其属性将是值为字符串的数组项的属性。

例如,如果我有这些构造函数:

function Person(name,pets){
        this.name=name;
        this.pets=pets;
    }
function Pet(name){this.name=name;}

这个数据:

var arr=[
        new Person("Bob",[
            new Pet("Sparky"),
            new Pet("Wishbone")
        ]),
        new Person("Mary",[
            new Pet("Maggie"),
            new Pet("Sprinkles")
        ])
    ];

我使用这个功能并且效果很好:

Array.prototype.toDocFrag=function(){
        return this.reduce(function(docFrag,currentItem){
            elem=document.createElement(currentItem.constructor.name.toLowerCase());
            for (prop in currentItem){
                if (typeof currentItem[prop]==="string") elem.setAttribute(prop,currentItem[prop])
                //if (currentItem[prop] instanceof Array) elem.appendChild(currentItem[prop].toDocFrag())
            }
            docFrag.appendChild(elem)
            return docFrag;
        },document.createDocumentFragment())
    }

如果我运行 arr.toDocFrag() ,我得到一个 docFrag,其内容为 <person name="Bob"></person><person name="Mary"></person>正如预期的那样。

但现在我想做的是使其递归,以便它看到“宠物”并将另一个 DocumentFragment 附加到每个 <person>所以我最终得到

<person name="Bob">
    <pet name="Sparky"></pet>
    <pet name="Wishbone"></pet>
</person>
<person name="Mary">
    <pet name="Maggie"></pet>
    <pet name="Sprinkles"></pet>
</person> 

取消注释掉我在代码中注释掉的行,我相信它应该可以工作。但由于某种原因arr.toDocFrag()刚刚返回 <pet name="Wishbone"></pet><pet name="Sprinkles"></pet>

我的逻辑有什么问题吗?我是否误解了Array.prototype.reduce或者递归函数?

谢谢!


脚注

*我所说的类名是指启动实例的构造函数的名称。

最佳答案

您的问题是 elemimplicitly global variable 。这对于您的第一个函数来说并不重要,但会完全搞乱递归函数,其中调用会覆盖调用者的 elem

使用 var statement在本地声明变量(prop 也缺少该变量)。并使用strict mode以获得此类行为的错误。

关于javascript - 递归函数中的 Array.prototype.reduce 产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30281043/

相关文章:

javascript - 是否可以在 window 或 window.location 上制作原型(prototype)?

javascript - 使用 jquery.fs.selecter,选择未重置

创建子进程可以访问的共享字符串数组

c++ - 正确转发到动态分配数组的特化

javascript - 通常如何比较两个 DOM 或 DOM 节点?

java - 如何在标签完好无损的情况下解析 html

javascript - 同步多个 Promise,同时允许多次重试

javascript - 未捕获的 TypeError : d. type.toUpperCase 不是函数

java - 在 Java 中表示 100K X 100K 矩阵

javascript - 为什么 DocumentFragment 会忽略一些附加节点?