文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

分析JavaScript浅拷贝和深拷贝

2023-06-25 12:49

关注

本篇内容主要讲解“分析JavaScript浅拷贝和深拷贝”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“分析JavaScript浅拷贝和深拷贝”吧!

一、直接赋值

对象是引用类型,如果直接赋值给另外一个对象,那么只是赋值一个引用,实际上两个变量指向的同一个数据对象,如果其中一个对象的属性变更,那么另外一个也会变更。

示例1,简单示例:

let human1 = {    id: 1,    name: "happy"};human2 = human1; // 这里就是直接赋值 console.log(human1); // {id: 1, name: 'happy'}console.log(human2); // {id: 1, name: 'happy'} // 更改human1的名称,human2的也会更改human1.name = "life";console.log(human1); // {id: 1, name: 'life'}console.log(human2); // {id: 1, name: 'life'}

示例2,对象作为参数传递也是传递引用:

let human1 = {    id: 1,    name: "happy"}; console.log(human1); // {id: 1, name: 'happy'} function foo(human) {    // 这里更改了human对象的名称    human.name = "life";}foo(human1); // 传递对象是传递引用 console.log(human1); // {id: 1, name: 'life'}

二、浅拷贝

浅拷贝只是复制了对象的第一层,如果第一层的属性值是对象,那么该属性也只是复制了一个引用。

let object1 = {    a: 1,    b: { // b是对象        b1: 2    }};object2 = Object.assign({}, object1); // 这里就是浅拷贝,其中的b对象只复制了引用 // a是常规类型,不会互相影响object1.a = 10;console.log(object1.a); // 10console.log(object2.a); // 1 // b是对象,会互相影响object1.b.b1 = 20;console.log(object1.b.b1); // 20console.log(object2.b.b1); // 20

如果要实现完整的复制,就要使用深拷贝。

三、深拷贝

森拷贝就是不光是一层要复制,里面的层如果是对象也要进行复制。

1. JSON对象的方式

如果对象可以确认是JSON对象,那么可以用JSON对象的方式。

沿用上面的例子:

let object1 = {    a: 1,    b: { // b是对象        b1: 2    }}; object2 = JSON.parse(JSON.stringify(object1)); // 深拷贝 // a是常规类型,不会互相影响object1.a = 10;console.log(object1.a); // 10console.log(object2.a); // 1 // b是对象,也不会互相影响object1.b.b1 = 20;console.log(object1.b.b1); // 20console.log(object2.b.b1); // 2

这边深拷贝的原理其实就是先把对象转成json字符串,然后再转成json对象,中间转成json字符串后就和原来的对象没有关系了。

这方法的优点:实现非常简单。

缺点:

如果有属性值是函数的话,那么无法进行复制,数据会丢失。
另外原型对象无法进行复制。

所以这种方式只适合对象确认是一个纯粹的json数据。

2. 递归复制

因为需要一层一层递进复制,很容想到用递归的方式,参考如下实现:

function deepCopy(source) {    // 如果不是对象或者是null则直接返回    if (typeof source !== 'object' || source === null) {        return source;    }     let target = {};    // 遍历复制属性    for (let k in source) {        if (!source.hasOwnProperty(k)) {            continue;        }         if (typeof source[k] === 'object') { // 如果是对象,则递归复制            target[k] = deepCopy(source[k]);            continue;        }         let descriptor = Object.getOwnPropertyDescriptor(source, k);        Object.defineProperty(target, k, descriptor);    }     return target;}

因为是一层一层复制,所以复制完成后,两个对象不会互相影响,并且也可以支持方法。

let object1 = {    a: 1,    b: { // b是对象        b1: 2    },    f: function() { // f是方法        console.log(3);    }};object2 = deepCopy(object1); // 深拷贝,也可以复制函数了。object1.f(); // 3object2.f(); // 3 // b是对象,也不会互相影响object1.b.b1 = 20;console.log(object1.b.b1); // 20console.log(object2.b.b1); // 2

复制原型对象

但是这个方法还存在一个问题,就是原型对象无法复制,稍微改进一下:

// 把 let target = {}; 改成如下方式// 保证原型也进行了复制let target = Object.create(Object.getPrototypeOf(source));

这样就可以了,来个示例验证一下:

function Human() {    this.id = 1;}Human.prototype.bar = function() {    console.log("bar");}; let human1 = new Human();human2 = deepCopy(human1); console.log("human1", human1);console.log("human2", human2);

查看下两个对象的原型:

深拷贝复制原型对象:

分析JavaScript浅拷贝和深拷贝

完美复制。

当然这样的方法也存在一个问题,就是递归本身存在如果层次过深,容易造成栈溢出的问题。但是在实务中也建议不要复制非常大的对象,应该有另外好的解决方法。

到此,相信大家对“分析JavaScript浅拷贝和深拷贝”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯