zoukankan      html  css  js  c++  java
  • 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"]]
    
    

    性能问题

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

  • 相关阅读:
    ubuntu下安装maven
    159.Longest Substring with At Most Two Distinct Characters
    156.Binary Tree Upside Down
    155.Min Stack
    154.Find Minimum in Rotated Sorted Array II
    153.Find Minimum in Rotated Sorted Array
    152.Maximum Product Subarray
    151.Reverse Words in a String
    150.Evaluate Reverse Polish Notation
    149.Max Points on a Line
  • 原文地址:https://www.cnblogs.com/yinxingen/p/9923479.html
Copyright © 2011-2022 走看看