js的浅拷贝和深拷贝

浅拷贝

浅拷贝自然就不用多少了,针对引用类型的拷贝,拷贝的是引用地址,上例子:

var a={name:'hanmeimei',age:22};
var b=a;
b.name='wanglei';
console.log(a)//打印结果 {name: "wanglei", age: 22}

还有一种ES6的方法object.assign(),上例子:

//例子1
var a={name:'hanmeimei',age:22,subject:{'math':90,'physical':100}};
var b=Object.assign({},a);
b.name='wanglei';
console.log(a)//打印结果 {name: "hanmeimei",age:22,subject:{'math':90,'physical':100}}


//例子2
var a={name:'hanmeimei',age:22,subject:{'math':90,'physical':100}};
var b=Object.assign({},a);
b.subject.math=80;
console.log(a)//打印结果 {name: "hanmeimei",age:22,subject:{'math':80,'physical':100}}

//细心的你一定发现了什么,没错Object.assign()只针对第一级根属性做深拷贝处理,其他的做浅拷贝处理

深拷贝

深拷贝就是针对引用类型做的拷贝处理,是为了解决同一引用类型所导致的改一处导致另外一处的值也发生了改变,这是我们开发过程中常常遇到的,下列总结几种深拷贝方法:

1. 迭代递归法

for...in...法

对对象进行迭代操作,对它的每个值进行递归深拷贝。


function isObject(o) {
    return (typeof o === 'object' || typeof o === 'function') && o !== null
}
// 迭代递归法:深拷贝对象与数组
function deepClone(obj) {
    if (!isObject(obj)) {
        throw new Error('obj 不是一个对象!')
    }
 
    let isArray = Array.isArray(obj)
    let cloneObj = isArray ? [] : {}
    for (let key in obj) {
        cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
    }
 
    return cloneObj

 Reflect 法 


function deepClone(obj) {
    if (!isObject(obj)) {
        throw new Error('obj 不是一个对象!')
    }
 
    let isArray = Array.isArray(obj)
    let cloneObj = isArray ? [...obj] : { ...obj }
    Reflect.ownKeys(cloneObj).forEach(key => {
        cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
    })
 
    return cloneObj
}

2. 序列化反序列化法

使用JSON对象的parse和stringify方法来实现深拷贝

function deepClone(obj){
    let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

它也只能深拷贝对象和数组,对于其他种类的对象,会失真。这种方法比较适合平常开发中使用,因为通常不需要考虑对象和数组之外的类型。

你可能感兴趣的:(js常规方法总结)