范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

js中的浅拷贝和深拷贝

  js的数据类型: 基本数据类型:String、Number、Boolean、Null、Undefined; 引用数据类型:Object(Array、Date、Function、RegExp)。
  基本数据类型和引用数据类型的区别: 基本数据类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。 引用数据类型:引用类型(object)是存放在堆内存中的,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况来进行特定的分配。 引用数据类型保存在堆内存中,然后在栈内存中保存了一个对堆内存中实际对象的引用,即数据在堆内存中的地址,JS对引用数据类型的操作都是操作对象的引用而不是实际的对象,如果obj1拷贝了obj2,那么这两个引用数据类型就指向了同一个堆内存对象,具体操作是obj1将栈内存的引用地址复制了一份给obj2,因而它们共同指向了一个堆内存对象;
  例如: var a = 1; b = a; // 栈内存会开辟一个新的内存空间,此时b和a都是相互独立的 b = 2; console.log(a); // 1
  例如: var arr = [1, 2, 3, 4]; arr1 = arr; //arr将栈内存的引用地址复制了一份给arr1,因而它们共同指向了一个堆内存对象; arr1[2] = 9; console.log(arr); //[1,2,9,4]
  基本数据类型值不可变: javascript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。 原始值是不可更改的:任何方法都无法更改(或"突变")一个原始值。 对数字和布尔值来说显然如此 —— 改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来假改字符串中的字符。 实际上,javascript 是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。
  基本数据类型的值是不可变的,动态修改了基本数据类型的值,它的原始值也是不会改变的, var str = "abc"; str[1] = "f"; console.log(str); //abc
  有很多操作字符串的方法,但是这些方法都是返回一个新的字符串,并没有改变其原有的数据。
  引用类型值可变 var a = [1, 2, 3]; a[1] = 5; console.log(a[1]); // 5
  浅拷贝 与 深拷贝: 浅拷贝和深拷贝都只针对于引用数据类型,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存;但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象;浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制。
  区分深拷贝与浅拷贝,就是假设B复制了A,当修改B时,看A是否会发生变化,如果A也跟着变了,说明这是浅拷贝,拿人手短,如果A没变,那就是深拷贝,自食其力。
  浅拷贝:
  for···in只循环第一层 function simpleCopy(obj1) {     var obj2 = Array.isArray(obj1) ? [] : {};     for (let i in obj1) {         obj2[i] = obj1[i];     }     return obj2; } var obj1 = {     a: 1,     b: 2,     c: {         d: 3     } } var obj2 = simpleCopy(obj1); obj2.a = 3; obj2.c.d = 4; console.log(obj1.a); // 1 console.log(obj2.a); // 3 console.log(obj1.c.d); // 4 console.log(obj2.c.d); // 4
  Object.assign()实现浅拷贝及一层的深拷贝 var obj1 = {     a: {         b: 1     },     c: 2 } var obj2 = Object.assign({}, obj1) obj2.a.b = 3; obj2.c = 3 console.log(obj1.a.b); // 3 console.log(obj2.a.b); // 3 console.log(obj1.c); // 2 console.log(obj2.c); // 3
  Object实现拷贝2,浅拷贝 var obj1 = {     a: 1,     b: 2,     c: {         d: 3     } } var obj2 = Object.create(obj1); obj2.a = 3; obj2.c.d = 4; console.log(obj1.a); // 1 console.log(obj2.a); // 3 console.log(obj1.c.d); // 4 console.log(obj2.c.d); // 4
  深拷贝
  1、递归实现深拷贝 function deepCopy(obj1) {     var obj2 = Array.isArray(obj1) ? [] : {};     if (obj1 && typeof obj1 === "object") {         for (var i in obj1) {             var prop = obj1[i]; // 避免相互引用造成死循环,如obj1.a=obj             if (prop == obj1) {                 continue;             }             if (obj1.hasOwnProperty(i)) {                 // 如果子属性为引用数据类型,递归复制                 if (prop && typeof prop === "object") {                     obj2[i] = (prop.constructor === Array) ? [] : {};                     arguments.callee(prop, obj2[i]); // 递归调用                 } else {                     // 如果是基本数据类型,只是简单的复制                     obj2[i] = prop;                 }             }         }     }     return obj2; } var obj1 = {     a: 1,     b: 2,     c: {         d: 3     } } var obj2 = deepCopy(obj1); obj2.a = 3; obj2.c.d = 4; console.log(obj1.a); // 1 console.log(obj2.a); // 3 console.log(obj1.c.d); // 3 console.log(obj2.c.d); // 4
  2、Object.create实现深拷贝1,但也只能拷贝一层 function deepCopy(obj1) {     var obj2 = Array.isArray(obj1) ? [] : {};     if (obj1 && typeof obj1 === "object") {         for (var i in obj1) {             var prop = obj1[i]; // 避免相互引用造成死循环,如obj1.a=obj             if (prop == obj1) {                 continue;             }             if (obj1.hasOwnProperty(i)) {                 // 如果子属性为引用数据类型,递归复制                 if (prop && typeof prop === "object") {                     obj2[i] = (prop.constructor === Array) ? [] : Object.create(prop);                 } else {                     // 如果是基本数据类型,只是简单的复制                     obj2[i] = prop;                 }             }         }     }     return obj2; } var obj1 = {     a: 1,     b: 2,     c: {         d: 3     } } var obj2 = deepCopy(obj1); obj2.a = 3; obj2.c.d = 4; console.log(obj1.a); // 1 console.log(obj2.a); // 3 console.log(obj1.c.d); // 3 console.log(obj2.c.d); // 4
  3、使用JSON.stringify和JSON.parse实现深拷贝 JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。 缺点: (1)如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是时间对象; (2)如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象; (3)如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失; (4)如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null; (5)JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor; (6)如果对象中存在循环引用的情况也无法正确实现深拷贝;
  以上,如果拷贝的对象不涉及上面讲的情况,可以使用JSON.parse(JSON.stringify(obj))实现深拷贝,但是涉及到上面的情况(除循环引用的情况外),可以考虑使用如下方法实现深拷贝。 function deepClone(data) {     const type = this.judgeType(data);     let obj;     if (type === "array") {         obj = [];     } else if (type === "object") {         obj = {};     } else {         // 不再具有下一层次         return data;     }     if (type === "array") {         // eslint-disable-next-line         for (let i = 0, len = data.length; i < len; i++) {             obj.push(this.deepClone(data[i]));         }     } else if (type === "object") {         // 对原型上的方法也拷贝了....         // eslint-disable-next-line         for (const key in data) {             obj[key] = this.deepClone(data[key]);         }     }     return obj; }   function judgeType(obj) {     // tostring会返回对应不同的标签的构造函数     const toString = Object.prototype.toString;     const map = {         "[object Boolean]": "boolean",         "[object Number]": "number",         "[object String]": "string",         "[object Function]": "function",         "[object Array]": "array",         "[object Date]": "date",         "[object RegExp]": "regExp",         "[object Undefined]": "undefined",         "[object Null]": "null",         "[object Object]": "object",     };     if (obj instanceof Element) {         return "element";     }     return map[toString.call(obj)]; }
  4、如果被拷贝中没有对时间、正则要求兼容,可以采用如下方法 function deepClone(obj){     let objClone = Array.isArray(obj)?[]:{};     if(obj && typeof obj==="object"){         for(key in obj){             if(obj.hasOwnProperty(key)){                 //判断ojb子元素是否为对象,如果是,递归复制                 if(obj[key]&&typeof obj[key] ==="object"){                     objClone[key] = deepClone(obj[key]);                 }else{                     //如果不是,简单复制                     objClone[key] = obj[key];                 }             }         }     }     return objClone; }
  5、热门的函数库lodash,也有提供_.cloneDeep用来做深拷贝
  6、jquery实现深拷贝,jquery 提供一个$.extend可以用来做深拷贝 var $ = require("jquery"); var obj1 = {     a: 1,     b: {         f: {         g: 1         }     },     c: [1, 2, 3] }; var obj2 = $.extend(true, {}, obj1); console.log(obj1.b.f === obj2.b.f);  // false

努比亚Z30Pro影像旗舰再升级,华米OV的多次学习的隐形标杆3月20日,努比亚新一代旗舰努比亚Z30Pro发布,与上一代整整相隔了651天。努比亚手机出身名门,事实上在手机摄影领域很多知名技术最初都是努比亚率先研发推出的,只可惜品牌度较低,戴森最新空气净化风扇,新技术亮点其他品牌又要开启抄袭进程4月27日,戴森在北京发布最新一代空气净化风扇系列DysonPurifierCoolFormaldehyde和DysonPurifierHotCoolFormaldehyde两款新不送充电器不怕,氮化镓征拓S3二代一头多口充电贼快朋友们现在的智能设备数量丰富得很,手机两个的不在少数,加之平板,笔记本等等更是不胜枚举。各种产品的充电适配器不在少数,插线板的孔位不怕多,就这往往还是不够的。看看下面两张图,多孔位网友纯粹的十年果粉怎么就换了华为mate40rs保时捷一直用苹果手机,一直不敢换华为,主要被苹果生态绑死了。尤其是今年买了iPadPro妙控键盘后,基本没有预料过自己会换华为。但这次的保时捷真心把我惊艳了。没错,是惊艳。有一次在专卖店vivoS9被歪果仁连连称赞,极暗环境下自拍效果惊人最近,备受用户喜爱的vivoS系列迎来了新成员vivoS9。而不出预料,作为vivoS系列最新一代的升级版,vivoS9一发布就凭借着高颜值的外观和出色的功能调校得到了众多用户的追这场华为发布会,智慧屏智能新品背后的野心更值得关注华为全屋智能及智慧屏旗舰新品发布会,笔者认为不在于华为能发布多少新品,有多少创新科技。其实更应关注其华为换赛道后,支持者的数量与质量!关注一鸿蒙HarmonyOS全屋智能主机为核心喵喵机智能错题学习机,错题整理解析打印样样行作为一款高效的学习智能硬件,作业帮旗下的喵喵机智能错题学习机很好地解决了学生的错题学习痛点,行业首创了拍搜打学一体的学习体验,随时随地都可以搞定错题!首先功能非常全面,WIFI,4和大家聊聊苹果为何力推iPhone12磁吸无线充电器1首先了解一下什么是磁吸无线充?iPhone12磁吸无线充可以简单的理解为在原有的无线充基础上加了一圈磁铁,通过磁铁的吸引力让手机与无线充电器准确定位配对,由此进入更高效率的无线充跟谁学更名高途表象背后,在线教育助推本地化,科技化4月22日,跟谁学更名高途集团媒体发布会在京召开,背后的战略的具体实施才是笔者最为关注的。高途集团前身跟谁学于2014年成立,于2019年在美上市,可见其近几年的发展是积累了丰富的雷军营销大师小米花200万设计新LOGO,不仅没亏还物超所值近日,小米又在网络上掀起了一波热议浪潮,这次引发大众关注和讨论的热门话题主要来源于三个方面。一方面是小米推出了自主研发的图像处理芯片澎湃芯片C1又一方面是雷军宣布小米正式进军智能电锐捷星耀X32PRO路由器复杂环境实测三个8特效加持真稳4月6日,锐捷星耀X32PRO正式在京东平台开启预售,作为一款针对大户型复杂户型用户专门研发的一款WiFi6路由器,锐捷星耀X32PRO有哪些自己的优势和特点呢?通过笔者的实际使用
Go语言自学系列golang通过接口实现OCP设计原则视频来源B站golang入门到项目实战2021最新Go语言教程,没有废话,纯干货!持续更新中一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!附上汇总贴GMySQL数据查询语言DQL数据连接语法及实例连接合并思想。N个表1个表连接的定义将2个或2个以上的表通过一定的条件拼接起来形成一个虚表的过程。连接是from子句的一部分。从2个表的连接开始。左表放置在你左手边的表。leftt欧盟新数字法加强科技巨头监管,若违规可能面临数十亿美元罚款环球时报综合报道欧盟23日就新的数字法规达成一致,将迫使谷歌和脸书母公司Meta等科技巨头更积极地监管其平台上的非法内容,否则可能面临数十亿美元的罚款。据法新社23日报道,新的数字全球首个月壤数字藏品发布,基于真实月壤扫描生成数字图像制成新京报贝壳财经讯(记者许诺)4月24日中国航天日,中国探月嫦娥公司在百度超级链上发行了全球首个月壤数字藏品。该月壤数字藏品是基于嫦娥五号带回的真实月壤,经技术人员用显微镜放大约25全球首个月壤数字藏品限量发行品玩4月24日讯,据36氪报道,中国探月工程重磅发布全球首个月壤数字藏品,由百度超级链提供技术支持。月壤数字藏品分别在百度App小度App各限量发行1731份,致敬嫦娥5号带回的1华为高管带薪摸鱼被曝光,我顿悟了职场中的5个残酷真相最近看到一则贴子华为某核心部门,有位18级技术大佬(从业10几年),天天早上8点来公司(送女儿上学)晚上6点走(接女儿放学),周六加班带薪看书,非工作时间基本不接电话。有一次,项目马斯克的地下隧道公司Boring获6。75亿美元C轮融资4月20日,TheBoringCompany(以下简称Boring公司)宣布,在C轮融资中获得6。75亿美元,这促使这家致力于创建地下隧道网络将交通3D化的公司目前的估值达到56。GoogleAds中国第一社群2022年04月24日一分钟跨境新闻分享GoogleAds中国第一社群跨境早报NO。1行业新闻1。亚马逊官宣在全球新增37个相关项目,包含3个风力发电场26个新太阳能发电场和8个屋顶太阳能装置2。亚马逊物流向第三方卖家开AITO问界M7官图发布六座布局增程式动力,纯电续航150km日前,车图腾从工信部申报目录中获得一组问界M7的新车外观官图。据悉,新车定位于中大型插电增程式电动SUV,采用222的六座布局。新车采用与问界M5相同的家族化设计语言,前脸可点亮品最值得买的4款大屏手机,颜值高性能强,最低1699萝卜白菜各有所爱,有人喜欢小屏手机,能够单手握持。有人喜欢大屏手机,因为看视频玩游戏很带劲。快哥也注意要越来越多的朋友开始用大屏,而且希望我整理下大屏手机,帮忙把把关。所以今天快哥全新配色升级美拍和性能,潮流手机小米Civi1S正式发布2299元起4月21日,小米正式发布小米Civi1S和小米智能家庭屏10两款重磅新品。小米Civi1S是专为年轻人打造的潮流手机,带来外观美拍和流畅三大升级。外观加入行业稀缺的奇迹阳光(白色)