简析JS对象深拷贝 阅读·536

码字不易,转载请注明本文链接 http://ymblog.net/2016/07/30/简析js对象深拷贝/

之所以会产生深拷贝这个问题,是因为将对象在进行浅拷贝赋值的时候,赋值的是它的引用地址,而并不是值,这就涉及到了JS基本的数据类型。

JS的基本数据类型,包含

  1. 原始的,简单的5中数据类型;
    • string,number,boolean,null,undefined
  2. 合成的,复杂的3种数据类型;
    • array,function,object

对于原始的数据类型,我们拷贝都是指的浅拷贝,复制以后就相当于是赋值。

而复杂的数据类型,如果我们进行浅拷贝都是指的对其地址的拷贝,即引用。


var test = [];
b-test = test;
b-test[0] = 1;
console.log(test); // [1]

如上面的代码所示。所以,我们拷贝对象的时候,要将它拆分为一个一个的原始数据类型再去拷贝,这样就达到了深拷贝的目的。


cloneObject: function (object) {
        var bak;
        if (object instanceof(Array)) {
            bak = [];
            for (var i =0; i< object.length; i++) {
                if (typeof object[i] == "object") arguments.callee(object[i]);
                else bak[i] = object[i];
            }
        } else {
            bak = {};
            for (var key in object) {
                if (typeof bak[key] == "object") {
                    arguments.callee(bak[key]);
                } else { // 包括函数在内 直接赋值了
                    bak[key] = object[key];
                }
            }
        }
        return bak;
    }

如上代码所示。利用递归对对象的每一项进行判断,如果是原始数据类型就直接赋值,否则继续遍历。这里用到了arguments的callee方法,区别见这篇文章:js callee,caller学习


init: function () {
    var clone = this.cloneObject(this.data);

    clone.name = "小明";
    clone.a[1] = "heheh";
    clone.bug = "heheh";
    clone.bug2 = function () { alert(1) };

    // console.log(this.data);
    // console.log(clone);
}

具体示例,见左下角查看代码演示,右键查看源码。

点击查看本文演示内容
相关文章
ES6箭头函数常见用法阅读·463 次 由js命名空间想到的函数声明预解析阅读·442 次 实现移动端网页图片按需加载阅读·1374 次 由移动端页面点击穿透想到的阅读·1111 次 jquery的deffered和promise方法阅读·839 次 由js图片预览想到的阅读·781 次 在webview中自定义js的confirm阅读·790 次 初识Vuejs阅读·1697 次 回首js正则表达式阅读·967 次 compass淘宝镜像安装失败阅读·1629 次
JMingZI

Jming依然 / 杭州

react.js/vue.js /pc端/ wordpress

博文分类

放荡不羁爱自由

博客信息

为了更美好的明天
日志总数:111篇
网站运行:888天
最后更新:2017年5月25日

站长统计: