浅拷贝和深拷贝

浅拷贝:不会复制属性中引用值里面的内容。
深拷贝:属性中的引用值里面的内容,也会复制。

浅拷贝

image.png

  1. //let shadowCopy = (sourse, target) => {
  2. //let tar = target || {}; //判断如果用户没有输入target,通过该语句添加一个空对象
  3. let shadowClone = sourse => {
  4. let target = {};
  5. for(let i in sourse){
  6. if(sourse.hasOwnProperty(i)){
  7. target[i] = sourse[i]; //中括号里面取得变量的值
  8. }
  9. }
  10. return target;
  11. }
  12. let person = {
  13. name: 'chen',
  14. age: '23',
  15. body: {
  16. weight: 68,
  17. height: 170
  18. }
  19. }
  20. let person1 = shadowClone(person);
  21. person1.name = 'qian';
  22. person.body.weight = 70;
  23. console.log(person1 === person); //false 可以看出person1指向另外开辟的内存空间
  24. console.log(person1.name === person.name); //false 改变person1的name值不会更改person的name值
  25. console.log(person1.body === person.body); //true
  26. console.log(person1.body.weight === person.body.weight); //true

内置对象浅拷贝方法

专门提供内置方法Object.assign(),实现的功能就是上面自己写的浅拷贝的实现代码

  1. /**
  2. *目的:掌握方法Object.assign()
  3. *参数:Object.assign(target,sourse[,sourse...]),源对象可以是多个
  4. *功能:通过遍历多个源对象属性 + hasOwnProperty()去除原型链上的属性,复制到目标对象
  5. *返回值:目标对象target
  6. */
  7. let person = {
  8. name: 'chen',
  9. age: '23',
  10. body: {
  11. weight: 68,
  12. height: 170
  13. }
  14. }
  15. let person1 = {
  16. name: 'qian'
  17. }
  18. let person2 = Object.assign({}, personperson1);
  19. console.log(person1 === person) //false

内置数组浅拷贝方法

数组浅拷贝方法slice()、concat()

let a = [1, 2, 3, 4, 5, [6, 7]];
let b = a.slice();
console.log(a === b);
b[5][0] = 8;
console.log(a[5][0]);   //8    浅拷贝

深拷贝

image.png

var deepClone = (sourse, tar) => {
    var target = tar || {};
    var toStr = Object.prototype.toString;    
    for(var key in sourse){
        if(sourse.hasOwnProperty(key)){
            if(typeof(sourse[key]) === 'object' && sourse[key] !== null){
                if(toStr.call(sourse[key]) === '[object Array]'){
                    target[key] = [];
                }else{
                    target[key] = {};
                }
                deepClone(sourse[key], target[key]);
            }else{
                target[key] = sourse[key];
            }                 
        }
    }
    return target;
}
let person = {
    name: 'chen',
    age: '23',
    body: {
        weight: '68',
        height: '170'
    },
    num: [1, 2, 3]
}
let person1 = deepClone(person);
console.log(person1,person);

//写法二,更好一点
let deepClone = sourse => {  
    let target = Array.isArray(sourse) ? [] : {};
    for(let key in sourse){     
        if(sourse.hasOwnProperty(key)){
            if(typeof sourse[key] === 'object' && sourse[key] !== null){        //不判断null
                target[key] = deepClone(sourse[key]);        //递归的返回值target,赋值给target[key]
            }else{
                target[key] = sourse[key];
            }            
        }                     
    }
    return target;
}
let person = {
    name: 'chen',
    age: '23',
    body: {
        weight: '68',
        height: '170'
    },
    num: [1, 2, 3],
    num1: null
}
let person1 = deepClone(person);
console.log(person1,person);

参考链接

https://github.com/daydaylee1227/Blog/blob/master/articles/JS/%E6%B7%B1%E6%8B%B7%E8%B4%9D%20vs%20%E6%B5%85%E6%8B%B7%E8%B4%9D.md