为了账号安全,请及时绑定邮箱和手机立即绑定

Reference and array clone

标签:
资讯

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 />").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 />").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 many 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 = $("<ul />").appendTo(rootNode);            $.each(kids, function(i, item) {                var liNode = $("<li />").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, []);    });
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
18
获赞与收藏
134

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消