OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

用jQuery和JavaScript深度复制JSON对象的方法


分享到
分类 JS学习   关键字 JavaScript   发布 ourjs  1438671315206
注意 转载须保留原文链接,译文链接,作者译者等信息。  
你有时可能需要复制一个JSON对象,jQuery提供了的extend方法以前是无法进行深度复制的,不过现在也已经支持了:

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

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


StackOverFlow的一位网友提供了一个深度复制的函数

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

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

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

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

        return encountered[0].b;
    }
    else {
        return this.slice(0);
    }
};

不过此函数是加到Array对象原型上的,这意味着你使用 for in 枚举array数组时也会枚举出这个方法。这里有一个函数版本:


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

    var types = [ Number, String, Boolean ], 
        result;

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

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

    return result;
}

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


其实深度复制JavaScript对象还有一个更加简单的方法, 一行代码即可,比如:

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


参考:http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object



原文地址: 点此
社区评论 ( Beta版 )
OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. JavaScript中的哈希表(Hash Maps的最佳实践)
  2. Node.js中的通用基础设计模式
  3. WowJS:在滚动页面时添加动画效果的简单实现
  4. 请停止将JavaScript类型化(建议不要使用class实现类继承)
  5. LightGL轻量级的WebGL 3D渲染库
  6. 闪客时代开始被HTML5慢慢终结:Facebook首席安全官号召设定正式消灭Flash的期限
  7. [PPT]JavaScript初级教程
  8. 在Debian/Ubuntu上面安装升级nginx到最新版
  9. 纽约时报使用Html5 WebRTC记录访问者IP地址
  10. AirJD-简单好用的免费建站工具

 相关阅读 - JS学习
  1. Node.js中的通用基础设计模式
  2. WowJS:在滚动页面时添加动画效果的简单实现
  3. [PPT]JavaScript初级教程
  4. JavaScript中的哈希表(Hash Maps的最佳实践)
  5. 我是怎么从顾虑到热爱ReactJS的(与AngularJS经典MVC数据绑定的对比)
  6. JSON序列化(stringify)对象时排除某些属性的两种方法
  7. JavaScript变量作用域(Variable Scope)和闭包(closure)的基础知识
  8. 用jQuery为跳转链接锚点添加平滑滚动动画效果(如回到顶部按钮)
  9. 用纯css改变下拉列表select框的默认样式
  10. Atom编辑器嵌入Node.JS引擎实践

 关键字 - JavaScript
  1. 如何用CSS将select/option文本居中或居右对齐
  2. 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能
  3. JavaScript中怪异的地方
  4. 在JavaScript中创建命名空间的几种写法
  5. JavaScript中的继承,构造函数以及new关键字的作用
  6. 纽约时报使用Html5 WebRTC记录访问者IP地址
  7. 正则中test、exec、match的简单区别,以及括号的用法
  8. NativeScript的工作原理:用JavaScript调用原生API实现跨平台
  9. 2015年的JavaScript:Angular之类的框架将被库取代
  10. 少年,不要滥用箭头函数啊:JS中lambda表达式的优缺点和使用场景

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号