• js


    在项目中,经常会用到拷贝。

    浅拷贝和深拷贝,相信大家都知道区别,但是怎么去实现呢?

    我会分享一些项目中经常会用到的一些方法,然后再手写一个深/浅拷贝的方法。

    1. Object.assign

    相信这个很多人都用过,用过就知道,这个在微信端,ie11或更低版本的ie上并不支持。所以我们就抛弃了这种方法。

    这种方法也只是浅拷贝,不能满足深拷贝的需求

    2. 通过es6的扩展运算符...来实现浅拷贝

    let a = {
      age: 1
    }
    let b = { ...a }
    a.age = 2
    console.log(b.age) // 1

    通常,浅拷贝只能解决部分问题。所以我们来看看深拷贝。

    3. JSON.parse(JSON.stringify(object))

    这个方法在项目中用的挺多的。

    let a = {
      age: 1,
      jobs: {
        first: 'FE'
      }
    }
    let b = JSON.parse(JSON.stringify(a))
    a.jobs.first = 'native'
    console.log(b.jobs.first) // FE

    但是该方法有局限性:

    • 会忽略 undefined
    • 会忽略 symbol
    • 不能序列化函数
    • 不能解决循环引用的对象

    自己实现一个深拷贝是很困难的,因为有很多便捷情况需要考虑。比如原型链,dom如何处理。所以我是根据项目实现的一个简易版的深、浅拷贝。

    推荐一个库: lodash

        var isObject = function(obj) {
            return obj !== null && (typeof obj === "object" || typeof obj === "function")
        };
    
        var clone = function(obj, deep) {
            if (!isObject(obj)) {
                throw new Error(obj + " is not object");
            }
            var newObj;
            var cloneArray = function(item) {
                var newItem = [];
                var size = item.length;
                for (var i = 0; i < size; i++) {
                    var vk = item[i];
                    if (deep && isObject(vk)) {
                        newItem[i] = clone(vk, deep);
                    } else {
                        newItem[i] = vk;
                    }
                }
                return newItem;
            };
            var cloneObject = function(item) {
                var newItem = {};
                Object.keys(item).forEach(function(n) {
                    var v = item[n];
                    if (deep && isObject(v)) {
                        newItem[n] = clone(v, deep);
                    } else {
                        newItem[n] = v;
                    }
                });
                return newItem;
            };
            if (obj instanceof Array) {
                newObj = cloneArray(obj);
                return newObj;
            }
    
            newObj = cloneObject(obj);
            return newObj;
        }

    测试代码:

        var obj1 = {
            a: 1,
            b: ["a", "b"]
        };
        var obj2 = {
            b: 2,
            c: obj1
        };
        var obj3 = clone(obj2, true);
        var obj4 = clone(obj2, false);
        obj1.b = ["a", "b", "c"];
        obj1.a = "2";
        console.log(obj3);
        console.log(obj4);

    输出结果:

     从结果可以看出:

    深拷贝obj3的结果不会因为引用类型obj1的改变而改变

    浅拷贝obj4的结果会因为引用类型obj1的改变而改变

  • 相关阅读:
    JS收集<3>:限制URL
    TSQL小收集<1>:为已经存在的表添加唯一约束
    第一个NHibernate实例 yangan
    用Javascript获取select的值 yangan
    获取页面名称语句 yangan
    asp.net中当服务器出错时显示指定的错误页面,同时把错误信息写入系统日志文件 yangan
    Log4Net使用指南 yangan
    明确自己的首要责任
    《大数据时代》摘录
    2013年3月阅读链接
  • 原文地址:https://www.cnblogs.com/thonrt/p/10334483.html
Copyright © 2020-2023  润新知