美文网首页
[前端]深拷贝和浅拷贝?怎么实现?

[前端]深拷贝和浅拷贝?怎么实现?

作者: 半颗糖嘿 | 来源:发表于2022-10-06 20:23 被阅读0次

浅拷贝:只是增加了一个指针,指向已经存在的内存地址。
仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅拷贝出来的对象也会相应的改变。
简单来说,就是改变其中一个对象,另一个对象也会跟着改变。

深拷贝:
是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
在计算机中开辟一块新的内存地址用于存放赋值对象。
简单的讲,就是复制出来的每个对象都有自己的内存空间,不会相互干扰。

深拷贝的三种实现方式:
1.常用JSON.parse(JSON.stringify(obj));====>先序列化,再反序列化。
缺点(bug)是: 会忽略undefined、symbol、funciton
2.jQuery中$.extend([deep],target,...object);

deep---表示深拷贝,Boolean类型;
target---目标对象;
...object---需要进行合并对象

3.利用原生js进行深拷贝-手写实现深拷贝
(1)for循环遍历所有属性(只拷贝当前对象的属性)----hasOwnProperty():返回布尔值。
(2)判断是引用数据类型,还是基本数据类型
①如果是基本数据类型:则使用浅拷贝拷贝;
②如果是引用数据类型,(object)
a.再判断是否为数组,如果为数组,则为target[key]赋值为[](数组),否则为{}对象。
b.接着再进行深拷贝(递归深拷贝)

function deepCopy(source,target){
    for(var key in source) {
        if(source.hasOwnProperty(key)){ // 只拷贝当前对象的属性
            // 判断是否为引用数据类型
            if(typeof source[key] == 'object'){
                // 引用数据类型,赋值为数组[]或者对象{},递归进行深拷贝。
                target[key] = Array.isArray(source[key])?[]:{};
                deepCopy(source[key],target[key]);
            } else {
                // 基本数据类型---浅拷贝
                target[key] = source[key];
            }
        }
    }
}

浅拷贝的实现方式:
(1)Object.assign()
Object.assign()是es6中对象的拷贝方法,接受的第一个参数是目标对象,其余参数是源对象,用法:Object.assign(target,source_1,...),该方法可以实现浅拷贝,也可以实现一维对象的深拷贝。
同样Object.assign可以做对象的合并
用法:将第2个参数开始的对象合并到第一个对象中

let newObj = Object.assign(...obj1,...obj2)//---如果是这样写,会改变原对象的数据
// 为了不破坏原对象,所以写入一个空对象{}
let newObj = Object.assign({},...obj1,...obj2)

eg:

let target = {a:1};
let object2 = {b:2};
let object3 = {c:3};
Object.assign(target,object2,object3);
console.log(target);// {a:1,b:2,c:3}

(2)es6的扩展运算符
使用扩展运算符可以在构造字面量对象的时候,进行属性的拷贝。
语法:let cloneObj = {..obj};
eg:

let obj1 = {a:1,b:{c:1}};
let obj2 = {...obj1};
obj1.a = 2;
console.log(obj1);// {a:2,b:{c:1}}
console.log(obj2);// {a:1,b:{c:1}}
obj1.b.c = 2;
console.log(obj1);// {a:2,b:{c:2}}
console.log(obj2);// {a:1,b:{c:2}}

(3)数组方法实现数组浅拷贝
a.Array.prototype.slice()
slice()方法是JavaScript数组的一个方法,这个方法可以从已有数组中返回选定的元素:
用法:array.slice(start,end),该方法不会改变原始数组
该方法有两个参数,两个参数都可选,如果两个参数都不写,就可以实现一个数组的浅拷贝。
eg:

let arr = [1,2,3,4]
console.log(arr);// [1,2,3,4]
console.log(arr.slice());// [1,2,3,4]
console.log(arr.slice()==arr);// false
console.log(arr.slice()===arr);// false

start:①提取起始处的索引(从0开始)
②如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)
eg:arr.slice(-2)//[3,4]
③如果省略start,则slice从索引0开始。
④如果start超出原数组的索引范围,则会返回空数组。
end:①提取终止处的索引(从0开始)。
slice会提取原数组中索引从start到end的所有元素(包括start,但不包括end)
②如果该参数为负数,则它表示在原数组的倒数第几个元素结束抽取。
eg:slice(-2,-1)//[3]→(抽取了原数组中的倒数第二个元素到最后一个元素但不包含最后一个元素)
③如果end被省略,则slice会一直提取到原数组末尾。
④如果end大于数组的长度,slice也会一直提取到原数组末尾。
b.Array.prototype.concat()
concat()方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
该方法有两个参数,两个参数都可选,如果两个参数都不写,就可以实现一个数组的浅拷贝。

let arr = [1,2,3,4];
console.log(arr);// [1,2,3,4]
console.log(arr.concat());// [1,2,3,4]
console.log(arr.concat()==arr);// false
console.log(arr.concat()===arr);// false

(4)手写实现浅拷贝

function shallowCopy(object) {
    // 只拷贝对象
    if(!object || typeof object !== 'object') return;
    // 根据object的类型判断是新建一个数组还是对象
    let newObject = Array.isArray(object)?[]:{};
    // 遍历object,并且判断是object的属性才拷贝
    for(let key in object) {
        if(object.hasOwnProperty(key)){
            newObject[key] = object[key];
        }
   }
    return newObject;
}

相关文章

  • 五、面试总结(五)

    对象 拷贝(clone) 如何实现对象克隆 深拷贝和浅拷贝区别 深拷贝和浅拷贝如何实现激活机制 写clone()方...

  • 深拷贝、浅拷贝

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • 面试题整理

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • js浅拷贝、深拷贝

    前言 本文主要简单讲一下什么是浅拷贝、什么是深拷贝、深拷贝与浅拷贝的区别,以及怎么进行深拷贝和怎么进行浅拷贝。 一...

  • js深拷贝浅拷贝

    目录 一.数据类型 二.浅拷贝与深拷贝 三.赋值和浅拷贝的区别 四.浅拷贝的实现方式 五.深拷贝的实现方式 一.数...

  • 面试 (一) : 基础篇

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。• 深拷贝同浅拷贝的区别:浅拷...

  • 基础

    1、父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅...

  • 常见的面试(一)

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。• 深拷贝同浅拷贝的区别:浅拷...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

网友评论

      本文标题:[前端]深拷贝和浅拷贝?怎么实现?

      本文链接:https://www.haomeiwen.com/subject/qousartx.html