JavaScript当中的浅拷贝和深拷贝

基本数据类型的赋值,当修改其中一个变量的数据的时候,另一个变量不受其影响。        --------------传值

但是当数据类型是引用数据类型的时候,通过变量赋值得到引用(堆栈问题),这时修改其中一个数据的时候,另一个变量也会同时更改。  --------------传址

但往往这种修改在实际开发中是不期望的。

因此JavaScript当中的深拷贝和浅拷贝在实际开发应用当中较为常见。

  

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

概念描述:

  浅拷贝(浅复制):

    浅拷贝在引用数据类型当中实际上拷贝的是(栈)内存当中的地址。(存在修改影响现象。)

    总结:浅拷贝仅仅拷贝了栈当中的数据。(基本数据类型数据和引用数据类型指针)

    确实实现了复制,表现为栈。

    浅拷贝的实现方式:

       1、等号赋值。(类似浅拷贝,但不是真正意义上的浅拷贝。等号赋值相当于引用的是同一个堆内存,但是浅拷贝是新开堆内存,嵌套以及二维数组涉及引用元堆内存址问题)

       2、Object.assign()

       3、ES6中的展开符     var swtObjCopy = {...swtObj}

       4、数组当中的浅复制 Array.prototype.slice [1,2,3,[1,2,3]],存在第一层第二层问题

       5、数组中的concat()连接两个数组。

       。。。。。。

   具体使用方法:        

var swtObj = {
    name: "swtObj",
    hobby:{
    iphone:"iphone11Pro",
    computer:"Mac",
    game:"王者荣耀"
  }
} var swtObjCopy = Object.assign({},swtObj);

//打印 console.log(swtObjCopy)
{ // name: "swtObj", // hobby: {iphone: "iphone11Pro", computer: "Mac",game:"王者荣耀"} // }  
swtObj.name = "swtObjCopy"; 
swtObj.hobby.game:"放弃游戏,前端不香吗"

//打印 console.log(swtObj)

{ // name: "swtObjCopy", // hobby: {iphone: "iphone11Pro", computer: "Mac",game:"放弃游戏,前端不香吗"} // }  
//打印   console.log(swtObjCopy)
{ // name: "swtObj", // hobby: {iphone: "iphone11Pro", computer: "Mac",game:"放弃游戏,前端不香吗"} // } 
 

  由此可见Object.assign()复制的对象,仅仅实现了第一层的复制 。  ------因此为浅拷贝。

 

 

  深拷贝(深复制):(真正意义上的copy)

  深拷贝就是在拷贝数据的时候,将数据的所有引用结构都拷贝一份。

  深拷贝不仅仅会拷贝基本数据类型还会拷贝引用数据类型。

  深拷贝需要新开堆内存,花销较大。深拷贝后的对象之间不受影响,相互独立。

  

    深拷贝方式:

      1、利用JSON达到深复制。----JSON.parse(JSON.stringify())

      需要注意的是:

      JSON实现深复制某些情况下是不能被正确复制的

        比如:忽略undefined,symbol对象,不能序列化函数,不能解决嵌套引用{a:1,{b:2}},不能处理正则表达式,

不能处理内置对象new Date()(因为实时变化,但是可以转为字符串解决)

 

      2、真正意义上的深复制就是浅拷贝一层然后递归复制。

        

   //定义检测数据类型的功能函数
    function checkedType(target) {
        return Object.prototype.toString.call(target).slice(8, -1)
    }
    //实现深度克隆---对象/数组
    function clone(target) {
        //判断拷贝的数据类型

        //初始化变量result 成为最终克隆的数据
        let result,
            targetType = checkedType(target)

        if (targetType === 'Object') {
            result = {}
        } else if (targetType === 'Array'){
            result = []
        } else {
            return target
        }

        //遍历目标数据
        for (let i in target) {

            //获取遍历数据结构的每一项值。
            let value = target[i]

            //判断目标结构里的每一值是否存在对象/数组
            if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {

                //对象/数组里嵌套了对象/数组   
                //继续遍历获取到value值
                result[i] = clone(value)
            }else{

                //获取到value值是基本的数据类型或者是函数。
                result[i] = value
            }
        }
        return result
    }

 

      3、热门的函数库lodash,也有提供_.cloneDeep用来做深拷贝。

 

      4、jquery 提供一个$.extend可以用来做深拷贝。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

posted @ 2020-04-21 17:18  Action_swt  阅读(137)  评论(0编辑  收藏  举报