Array.prototype.reduce 在递归函数中产生了意想不到的结果

Array.prototype.reduce in recursive function is producing unexpected results

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

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

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(),我会得到一个包含预期内容 <person name="Bob"></person><person name="Mary"></person> 的 docFrag。

但现在我想做的是使其递归,以便它看到 "pets" 并将另一个 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 或递归函数有什么误解吗?

谢谢!


脚注

*class 名称是指启动实例的构造函数的名称。

你的问题是 elem 是一个 implicitly global variable。这对您的第一个函数无关紧要,但完全搞乱了递归函数,其中调用覆盖了他的调用者的elem

使用 var statement to declare your variables locally (it's missing for prop as well). And use strict mode 获取此类行为的错误。