In JavaScript, object and array are passed by reference.
Sometimes you may come into trouble if you don't keep this in mind, especial in
Recursion.
Let's see an example:
First, prepare a JavaScript array to present a tree data:
VaR treedata = [{"name": "root1", "kids": [{"name": "leaf1" },{ "name": "leaf2"}]}, {"name": "root2"}];
The expected HTML structure is:
<Ul> <li> root1 <ul> <li> leaf1 </LI> <li> leaf2 </LI> </ul> </LI> <li> root2 </ LI> </ul>
Our JavaScript code:
Function resolvetree (rootnode, kids) {var ulnode =$ ("<uL/> "). appendto (rootnode); $. each (kids, function (I, item) {var linode =$ ("<li/>" example .html (item. name ). appendto (ulnode); If (item. kids) {resolvetree (linode, item. kids) ;}}) ;}resolvetree ($ ("# tree"), treedata );
Next, we want to store the tree node's path.
For example, leaf1-[root1, leaf1], leaf2-[root1, leaf2], root2-[root2]
We modifiy the resolvetree function:
Function resolvetree (rootnode, kids, PATH) {var ulnode =$ ("<uL/> "). appendto (rootnode); $. each (kids, function (I, item) {var linode =$ ("<li/>" example .html (item. name ). appendto (ulnode); Path. push (item. name); linode. data ("path", PATH ). click (function (event) {event. stoppropagation (); alert ($ (this ). data ("path");}); If (item. kids) {resolvetree (linode, item. kids, PATH);} path. pop () ;}) ;}resolvetree ($ ("# tree"), treedata, []);
The logic must be right, but the result is suprising.
No matter which node I click, the Alert box contains an empty string.
What's the matter?
Oh... The array is passed by reference ....
The variable path in the code-linode. Data ("path", PATH)-is a reference. Then
We want a clone of the array.
There are using method to create a array clone.
// Method 1 var newarray = []; for (VAR I = 0; I <oldarray. length; I ++) {newarray. push (oldarray [I]);} // method 2 var newarray = oldarray. slice (0); // method 3 var newarray = []. concat (oldarray );
The final solution:
$ (function () {var treedata = [{"name": "root1", "kids": [{"name": "leaf1 "}, {"name": "leaf2"}]}, {"name": "root2"}]; function resolvetree (rootnode, kids, PATH) {var ulnode = $ ("
"). appendto (rootnode); $. each (kids, function (I, item) {var linode =$ ("
" example .html (item. name ). appendto (ulnode); Path. push (item. name); linode. data ("path", []. concat (PATH )). click (function (event) {event. stoppropagation (); alert ($ (this ). data ("path");}); If (item. kids) {resolvetree (linode, item. kids, PATH);} path. pop () ;}) ;}resolvetree ($ ("# tree"), treedata, []) ;});