• JS的深浅拷贝


    项目中根据各种需求或多或少会需要用到拷贝,通过查询整理之后今天简单的记录一下。

    我们可以利用 slice、concat 返回一个新数组的特性可以实现数组的拷贝。

    var arr = ['a', 1, true, null, undefined];
    var new_arr = arr.concat();
    console.log(arr) // ["a", 1, true, null, undefined]
    console.log(new_arr) // ["a", 1, true, null, undefined]
    
    var arr = ['a', 1, true, null, undefined];
    var new_arr = arr.slice();
    console.log(arr) // ["a", 1, true, null, undefined]
    console.log(new_arr) // ["a", 1, true, null, undefined]
    
    
    

    我们会发现,无论是新数组还是旧数组都发生了变化,也就是说使用 concat 方法,克隆的并不彻底。这里可以联系值传递和引用传递、栈内存和堆内存的问题:如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。

    那如何深拷贝一个数组呢?这里介绍一个技巧,不仅适用于数组还适用于对象!那就是:

    var arr = ['a', 1, true, ['old1', 'old2'], {old: 1}]
    var new_arr = JSON.parse( JSON.stringify(arr) );
    console.log(arr);
    console.log(new_arr);
    

    以上三个方法 concat、slice、JSON.stringify 都算是技巧类,可以根据实际项目情况选择使用,接下来我们思考下如何实现一个对象或者数组的浅拷贝。

    浅拷贝的实现:

    遍历对象,然后把属性和属性值都放在一个新的对象就好了

    var copy = function(obj) {
        // 只拷贝对象
        if (typeof obj !== 'object') return;
        // 根据obj的类型判断是新建一个数组还是对象
        var newObj = obj instanceof Array ? [] : {};
        // 遍历obj,并且判断是obj的属性才拷贝
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                newObj[key] = obj[key];
            }
        }
        return newObj;
    }
    var arr = [{a:"1"},["2"]];
    var newarr = copy (arr);
    console.log(newarr);//[{a:"1"},["2"]]
    
    

    深拷贝的实现

    我们在浅拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用浅拷贝函数

    var deepCopy = function(obj) {
        // 只拷贝对象
        if (typeof obj !== 'object') return;
        // 根据obj的类型判断是新建一个数组还是对象
        var newObj = obj instanceof Array ? [] : {};
        // 遍历obj,并且判断是obj的属性才拷贝
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
               /* if(typeof obj[key] === "object"){
                    newObj[key] = deepCopy(obj[key]);
                }else{
                    newObj[key] = obj[key];
                }*/
               newObj[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key]
            }
        }
        return newObj;
    }
    var arr = [{a:"1"},["2"]];
    var newarr = deepCopy(arr);
    console.log(newarr);//[{a:"1"},["2"]]
    
    

    性能问题

    尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

  • 相关阅读:
    随机产生16进制颜色值
    关于单元测试的思考--Asp.Net Core单元测试最佳实践
    使用xUnit为.net core程序进行单元测试
    SQLSERVER——查看阻塞信息(sp_who_lock优化无误版)
    SQLServer连接查询之Cross Apply和Outer Apply的区别及用法
    .netcore 写日志(使用NLog,log4net)
    概率与影响矩阵
    WebApi Helper帮助文档 swagger
    C# 使用HttpWebRequest Post提交数据,携带Cookie和相关参数示例
    解决哈希(HASH)冲突的主要方法
  • 原文地址:https://www.cnblogs.com/yinxingen/p/9923479.html
Copyright © 2020-2023  润新知