前端面试之深浅拷贝的不同写法

102 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

内容前言

这个小文章将深浅拷贝的不同实现方法,进行了书写,并且在浅拷贝是将ES3-->ES6的相关知识点进行了复习,在深拷贝时将不同实现深拷贝的方法做了实现。那我们就开始吧!

如果喜欢(❤ ω ❤)点个赞吧!!

深浅拷贝的异同

针对深浅拷贝,其中浅拷贝只是复制一层,其中如果时地址引用的化就会使得在拷贝过后指向堆内存中的同一个对象,在修改过后堆内存中的数据就会改变。而深拷贝是将多内存的数据也会进行拷贝,产生两个互不影响的数据。那接下来我们开始讲解!!!

浅拷贝

ES3的书写方式

在ES3中采用的就是for...in来进行遍历,这事最早的js的实现的方法。

function shallwCopy(obj){
    var copyObj = {}
    //for... in 是返回键名
    for(let per in obj){
        if(src.hasOwnProperty(per)){
            copyObj[per] = src[per]
        }
    }
    return copyObj
}

ES5的书写方式

在在ES5中添加了新的方法Object.getOwnPropertyNames() 返回结果是一个数组;Object.getOwnPropertyDescriptor()返回描述对象以及Object.defineProperty()

Object.getOwnPropertyNames(obj).forEach(function(key){
    //copyObj[key] = obj[key]
    var des = Object.getOwnPropertyDescriptor(obj, key)
    Object.definePropwety(copyObj, key, des)
})

ES6的写法

ES6 增加了对象的几个方法,其中

  1. Object.keys()返回键名数组
  2. Object.values()返回value的数组
  3. Object.entries()返回对象内键值的数组[["a",a],["b",b]]
  4. for...of方法是ES6中具有迭代器属性的一种遍历方法可以返回键值

对于for..of方法大家可以去看一看在ES6中迭代器的内容, 这里涉及到了具有迭代器属性的知识。在ES6中,数组、Set、Map、字符串都是可迭代对象。

function shallwCopy(obj){
    var copyObj = {}
    // for(let key of Object.keys(obj)){
    //     copyObj[key] = obj[key]
    // }
    for(let [key, value] of Object.entries(obj)){
        copyObj[key] = value
    }
    
}

深拷贝

深拷贝是进行每一层的遍历,进行储存 递归 递归一定要有结束条件。

递归

  1. 在递归中需要注意的点和涉及到的知识:
  2. 使用typeof对于null的判断类型也是object所以要设置两个条件
  3. instanceof是通过判断对象的原型对象来进行的
  4. Array.isArray()是ES6新增的知识
function deepClone(obj, cloneObj){
    var cloneObj = cloneObj || {}
    for(var i in obj){
        //因为typeof对于null的判断类型也是object所以要设置两个条件
        if(typeof obj[i] = 'object' && obj[i] !== null){
            // cloneObj[i] =Array.isArray(obj[i]) ? []:{}
            //cloneObj[i] = obj[i] instanceof Array ? []:{}
            cloneObj[i]=Object.toString.call(obj[i]).slice(8, -1) === 'Array'? []:{}
            deepClone(obj[i], cloneObj[i])
        }else{
            cloneObj[i] = obj[i]
        }
    }
    return cloneObj
}

JSON

如果对象中包含function或RegExp这些就不能用这种方法了。

function deepClone(obj){
    return JSON.parse(JSON.stringify(obj))
}

jQuery

jQuery中提供了extend方法extend(true,cloneObj,obj),第一个参数代表了要开启深拷贝。

function deepClone(obj){
    return $.extend(trun, {}, obj)
}

函数库lodash

lodash库是一个集合个各种处理方法的函数库,属于依赖包,在可以通过npm进行引入。它对外暴露一个_函数。在前端的开发过程中,经常会用到的一个很常用的工具库就是lodash。lodash是对各种方法、函数的封装,使得使用更加方便,具体的使用方法可以参见lodash官网中的介绍。 loash的链接(大家可以去看一下很实用的工具哦):www.lodashjs.com/

function deepClone(obj){
    return cloneObj = _.cloneDeep(obj)
}