一起来实现深拷贝

61 阅读1分钟

JS深拷贝实现

我发现很多javascript程序员在实现对象深拷贝的时候,主要有两种方式:

  • JSON序列化与序列化解析
  • 第三方库-loadash-es

JSON序列化与序列化解析

这种方式的实现其实算简单高效,但是不能覆盖很多场景,比如当目标中存在function时没法还原解析,会报错;

 let a= {name: 'a'}; let a_copy= JSON.parse(JSON.stringtify(a));  //只有值和对象时OK

 let a= {name: 'a', log: data=>{console.log(data)}};     

 let a_copy= JSON.parse(JSON.stringtify(a));

 a_copy.log(123);  //报错

第三方库-loadash

 import {deepClone} from 'loadash';
 let a= {name: 'a',log: data=>{console.log(data)}}; 
 let a_copy= deepClone(a);
 a_copy.log(123); //ok

这个方法可以支持JSON方法的不足,但是需要引入第三方库,我个人不是很喜欢,我喜欢自己造轮子。

自己实现

/**
 *  @todo 深拷贝
 *  @params {Object|Array} ob - 拷贝的对象
 *  @return {Object|Array}
 *  */  

function deepClone(ob){
  let _new= Array.isArray(ob)? [] : {}
  function isObject(data){
    return data.constructor.prototype.toString() === '[object Object]'
  }
  function copy(sob, _snew){
    if(Array.isArray(sob)){ //数组
        sob.forEach( (item,index) => {
            if(item && isObject(item)){
                copy(item, _snew[index]={})
            }else if(item && Array.isArray(item)){
                copy(item, _snew[index]=[])
            }else{
                _snew[index]= item
            }
        })
    }else{ //对象
        let keys = Object.keys(sob)
        keys.forEach(key => {
            if(sob[key] && isObject(sob[key])){ //对象
                _snew[key]={}
                copy(sob[key], _snew[key])
            }else if(sob[key] && Array.isArray(sob[key])){ //数组
                copy(sob[key], _snew[key]=[])
            }else{
                _snew[key]= sob[key]
            }
        })
    }
  }
  copy(ob, _new)
  return _new
}