zoukankan      html  css  js  c++  java
  • 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, []);
        });
  • 相关阅读:
    “终身幼儿园”:学习是一个创造的过程
    我对ERP实质的理解(陈启申)
    Java学习记录1java并发编程之synchronized初学
    谈谈你对Spring的理解
    java中的==与equals的区别
    Windows下编译安装perl Module
    win系统用virtualBox安装Ubuntu虚拟机,如何共享数据
    Windows下emacsw3m设置代理
    自我介绍
    document 对象
  • 原文地址:https://www.cnblogs.com/sanshi/p/1514064.html
Copyright © 2011-2022 走看看