I'm trying write a function to convert an Array to a DocumentFragment. Each item of the array will become an HTMLElement. It's tag name will be the array-item's class name*, and its attributes will be the properties of the array-item whose values are strings.
So for example, if I have these constructors:
function Person(name,pets){
this.name=name;
this.pets=pets;
}
function Pet(name){this.name=name;}
And this data:
var arr=[
new Person("Bob",[
new Pet("Sparky"),
new Pet("Wishbone")
]),
new Person("Mary",[
new Pet("Maggie"),
new Pet("Sprinkles")
])
];
I use this function and it works great:
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())
}
If I run arr.toDocFrag()
, I get a docFrag with the contents <person name="Bob"></person><person name="Mary"></person>
as expected.
But now what I want to do is make it recursive, so that it sees "pets" and appends another DocumentFragment to each <person>
so I end up with
<person name="Bob">
<pet name="Sparky"></pet>
<pet name="Wishbone"></pet>
</person>
<person name="Mary">
<pet name="Maggie"></pet>
<pet name="Sprinkles"></pet>
</person>
Uncomment out the line I commented out in my code, and I believe that it should work. But for some reason arr.toDocFrag()
is returning just <pet name="Wishbone"></pet><pet name="Sprinkles"></pet>
What is wrong with my logic? Am I misunderstanding something about Array.prototype.reduce
or recursive functions?
Thanks!
Footnote
*By class name I mean the name of the constructor that initiates the instance.
Your problem is that elem
is an implicitly global variable. This doesn't matter for your first function, but completely messes up the recursive function where a call overwrites elem
of his caller.
Use a var
statement to declare your variables locally (it's missing for prop
as well). And use strict mode to get errors on such behaviour.