用jQuery和JavaScript深度復制JSON對象的方法

jopen 9年前發布 | 25K 次閱讀 JSON Ajax框架

你有時可能需要復制一個JSON對象,jQuery提供了的extend方法以前是無法進行深度復制的,不過現在也已經支持了:

// Shallow copy
var newObject = jQuery.extend({}, oldObject);

// Deep copy var newObject = jQuery.extend(true, {}, oldObject);</pre>


</div> </div>


StackOverFlow的一位網友提供了一個深度復制的函數


   
Array.prototype.clone = function(doDeepCopy) {
    if(doDeepCopy) {
        var encountered = [{
            a : this,
            b : []
        }];

</div>
<div>
            var item,
</div>
<div>
                levels = [{a:this, b:encountered[0].b, i:0}],
</div>
<div>
                level = 0,
</div>
<div>
                i = 0,
</div>
<div>
                len = this.length;
</div>
<div>

</div>
<div>
            while(i < len) {
</div>
<div>
                item = levels[level].a[i];
</div>
<div>
                if(Object.prototype.toString.call(item) === "[object Array]") {
</div>
<div>
                    for(var j = encountered.length - 1; j >= 0; j--) {
</div>
<div>
                        if(encountered[j].a === item) {
</div>
<div>
                            levels[level].b.push(encountered[j].b);
</div>
<div>
                            break;
</div>
<div>
                        }
</div>
<div>
                    }
</div>
<div>
                    if(j < 0) {
</div>
<div>
                        encountered.push(j = {
</div>
<div>
                            a : item,
</div>
<div>
                            b : []
</div>
<div>
                        });
</div>
<div>
                        levels[level].b.push(j.b);
</div>
<div>
                        levels[level].i = i + 1;
</div>
<div>
                        levels[++level] = {a:item, b:j.b, i:0};
</div>
<div>
                        i = -1;
</div>
<div>
                        len = item.length;
</div>
<div>
                    }
</div>
<div>
                }
</div>
<div>
                else {
</div>
<div>
                    levels[level].b.push(item);
</div>
<div>
                }
</div>
<div>

</div>
<div>
                if(++i == len && level > 0) {
</div>
<div>
                    levels.pop();
</div>
<div>
                    i = levels[--level].i;
</div>
<div>
                    len = levels[level].a.length;
</div>
<div>
                }
</div>
<div>
            }
</div>
<div>

</div>
<div>
            return encountered[0].b;
</div>
<div>
        }
</div>
<div>
        else {
</div>
<div>
            return this.slice(0);
</div>
<div>
        }
</div>
<div>
    };
</div>

</pre>


不過此函數是加到Array對象原型上的,這意味著你使用 for in 枚舉array數組時也會枚舉出這個方法。這里有一個函數版本:



   
function clone(item) {
    if (!item) { return item; } // null, undefined values check

</div>
<div>
        var types = [ Number, String, Boolean ], 
</div>
<div>
            result;
</div>
<div>

</div>
<div>
        // normalizing primitives if someone did new String('aaa'), or new Number('444');
</div>
<div>
        types.forEach(function(type) {
</div>
<div>
            if (item instanceof type) {
</div>
<div>
                result = type( item );
</div>
<div>
            }
</div>
<div>
        });
</div>
<div>

</div>
<div>
        if (typeof result == "undefined") {
</div>
<div>
            if (Object.prototype.toString.call( item ) === "[object Array]") {
</div>
<div>
                result = [];
</div>
<div>
                item.forEach(function(child, index, array) { 
</div>
<div>
                    result[index] = clone( child );
</div>
<div>
                });
</div>
<div>
            } else if (typeof item == "object") {
</div>
<div>
                // testing that this is DOM
</div>
<div>
                if (item.nodeType && typeof item.cloneNode == "function") {
</div>
<div>
                    var result = item.cloneNode( true );    
</div>
<div>
                } else if (!item.prototype) { // check that this is a literal
</div>
<div>
                    if (item instanceof Date) {
</div>
<div>
                        result = new Date(item);
</div>
<div>
                    } else {
</div>
<div>
                        // it is an object literal
</div>
<div>
                        result = {};
</div>
<div>
                        for (var i in item) {
</div>
<div>
                            result[i] = clone( item[i] );
</div>
<div>
                        }
</div>
<div>
                    }
</div>
<div>
                } else {
</div>
<div>
                    // depending what you would like here,
</div>
<div>
                    // just keep the reference, or create new object
</div>
<div>
                    if (false && item.constructor) {
</div>
<div>
                        // would not advice to do that, reason? Read below
</div>
<div>
                        result = new item.constructor();
</div>
<div>
                    } else {
</div>
<div>
                        result = item;
</div>
<div>
                    }
</div>
<div>
                }
</div>
<div>
            } else {
</div>
<div>
                result = item;
</div>
<div>
            }
</div>
<div>
        }
</div>
<div>

</div>
<div>
        return result;
</div>
<div>
    }
</div>
<div>

</div>
<div>
    var copy = clone({
</div>
<div>
        one : {
</div>
<div>
            'one-one' : new String("hello"),
</div>
<div>
            'one-two' : [
</div>
<div>
                "one", "two", true, "four"
</div>
<div>
            ]
</div>
<div>
        },
</div>
<div>
        two : document.createElement("div"),
</div>
<div>
        three : [
</div>
<div>
            {
</div>
<div>
                name : "three-one",
</div>
<div>
                number : new Number("100"),
</div>
<div>
                obj : new function() {
</div>
<div>
                    this.name = "Object test";
</div>
<div>
                }   
</div>
<div>
            }
</div>
<div>
        ]
</div>
<div>
    })
</div>

</pre>



其實深度復制JavaScript對象還有一個更加簡單的方法, 一行代碼即可,比如:


var cloned = JSON.parse(JSON.stringify(objectToClone));




原文地址: stackoverflow.com
</div>
來自:http://ourjs.com/detail/55c061d3fbd23139de9e3551

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!