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, []);
        });
  • 相关阅读:
    项目总结—jQuery EasyUI- DataGrid使用
    浅谈Dynamic 关键字系列之三(上):ExpandoObject, DynamicObject, DynamicMetaObject
    巧用section在cshtml写入layout中写入head信息 ASP.NET MVC
    ASP.NET MVC Web API 学习笔记---第一个Web API程序
    JSON详解
    【js】JSON.stringify 语法实例讲解
    Linux软件安装方法
    链接文件之硬链接和软链接
    Linux操作系统启动界面(字符or图形界面)的设置及切换方法
    Linux操作系统安装与VMTools的安装
  • 原文地址:https://www.cnblogs.com/sanshi/p/1514064.html
Copyright © 2011-2022 走看看