博客地址:https://ainyi.com/72 JavaScript 程序中,对于简单的数字、字符串可以通过 = 赋值拷贝 但是对于数组、对象、对象数组的拷贝,就有浅拷贝和深拷贝之分 浅拷贝就是当改变了拷贝后的数据...a // { name: 'krry' } b // { name: 'lily' } --- 以上是简单数组、对象的深拷贝方法,但是对于二维数组、对象数组、对象里包含对象,以上方法均达不到深拷贝方法...以上只能达到数组、对象的第一层的==深拷贝==,对于里面的数组或对象属性则是==浅拷贝==,因为里面的内存地址只是拷贝了一份,但都是指向==同一个地址== 所以当改变数组、对象里的数组元素或对象,原数据依然会改变...二维数组、对象数组、多层对象的深拷贝 最常用的 JSON 序列化与反序列化 使用 JSON.parse(JSON.stringify(obj)) let a = [1, [2, {aa: 2}, [4...拷贝的对象的值中如果有函数、undefined、symbol,则经过 JSON.stringify() 序列化后的 JSON 字符串中这个键值对会消失 无法拷贝不可枚举的属性,无法拷贝对象的原型链 拷贝
以上是背景,所以我就对浅拷贝和深拷贝进行了总结: 浅拷贝 什么是浅拷贝:两者是指向一个对象。 对象的浅拷贝 1、对象的直接遍历赋值。...数组的浅拷贝 (两者指向不同的对象,但是只能拷贝一层) array.concat(); array.slice(0); 如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里...两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变,所以是浅拷贝。...深拷贝 (下面说的深拷贝是基本对象的深拷贝,不考虑对象的复杂属性,比如set,get,Function等) 1、最简单的方式 JSON.parse(JSON.stringify(Obj)) 这种方法使用较为简单...,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。
1. object.assign object.assign 是 ES6 中 Object 的一个方法,该方法可以用于JS 对象的合并等多个用途,其中一个用途就是可以进行浅拷贝。...如果存在对象的嵌套,那么浅拷贝将无能为力。因此深拷贝就是为了解决这个问题而生的,它能解决多层对象嵌套问题,彻底实现拷贝。...深拷贝则不同,对于复杂引用数据类型,其在堆内存中完全开辟了一块内存地址,并将原有的对象完全复制过来存放。 深拷贝后的对象与原始对象是相互独立、不受影响的,彻底实现了内存上的分离。...总的来说,深拷贝的原理可以总结如下: 将原对象从内存中完整地拷贝出来一份给新对象,并从堆内存中开辟一个全新的空间存放新对象,且新对象的修改并不会改变原对象,二者实现真正的分离。 1....实现深拷贝方法 下面是一个实现 deepClone 函数封装的例子,有几点需要注意下。
这里就是出现了题目所谈到的问题,涉及到了js对象的直接赋值、浅拷贝与深拷贝。 直接赋值 把一个对象a赋值给一个对象b相当于把一个对象b的地址指向对象a的地址,所以,他们实际上是同一个对象。...图5 扩展运算符实现浅拷贝(赋值"小刚"等的操作与之前的结果完全相同,就不全贴出来了) 考虑到es6的支持程度,如果你的项目不支持es6,但是又想实现浅拷贝的话,也可以尝试js原生的concat方法...图6 concat方法实现浅拷贝 深拷贝 深拷贝会另外拷贝一份一个一模一样的对象,但是不同的是会从堆内存中开辟一个新的区域存放新对象,新对象跟原对象不再共享内存,修改赋值后的对象b不会改到原对象a。...即深拷贝,修改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也不会影响原对象a的对象属性。而且,二者不指向同一个对象。 ...很明显,深拷贝比较符合我这次的业务需求。深拷贝,比较笨一点的办法就是将自己需要的数据自己封装起来。
浅拷贝和深拷贝的'深浅'主要针对的是对象的‘深度’,常见的对象都是'浅'的,也就是对象里的属性就是单个的属性,而'深'的对象是指一个对象的属性是另一个对象,也就是对象里面嵌套对象,就像嵌套函数一样。...为什么要使用深拷贝和浅拷贝呢?...,obj1的改动也会影响到obj2,这不是我们所希望的,所以要用到深拷贝和浅拷贝。...深拷贝和浅拷贝就是为解决对象的直接赋值后依然'连接'的问题,也就是共用一个引用,一个改变会影响到另一个。...Paste_Image.png 通过上述代码可看出深拷贝拷贝的非常彻底,做到真正意义上的杜绝共用一个引用的问题。
浅拷贝 ---- 浅拷贝: 只是拷贝了基本类型的数据,而引用类型的数据,复制后还会发生引用 示例数据 const user = { name: 'liang', age: 23 } 在 js 中,引用类型的数据使用...(user) // {name: 'my name is liang', age: 23} 我们有以下几种方案可以进行浅拷贝 // 方案一: 使用 for in 循环取出属性和值,赋值给一个新的对象 const...深拷贝 ---- 深拷贝: 拷贝基本类型和引用类型的数据,而不是拷贝引用类型的引用 数据示例 const user = { name: 'liang', info: { age: 23 }, array...: ['html', 'css', 'javascript'], show(name) { return `${name} call show method` } } 深拷贝对象-迭代递归法 // 深拷贝对象...copy(value) : value; } return data } // 拷贝对象 const profile = copy(user) // 修改通过拷贝得到的变量不会影响原数据 profile.name
学习一下vuex的deepCopy源码 https://github.com/vuejs/vuex/blob/dev/src/util.js#L22 注释 我直接把第29行用的find函数放到里面了..., 这样好看一点 /** * 深拷贝 * @param {*} obj 拷贝对象(object or array) * @param {*} cache 缓存数组 */ function deepCopy...image 2.typeof方法对应的是基本类型 检测数组和对象返回都是'object' ?...image 注: 如果要区分数组和对象, 使用使用 Array.isArray 或者 Object.prototype.toString.call 3.基本原理 就是使用递归对数组或者对象进行每一项的复制...image 深拷贝的另一个简单的方法 直接使用JSON.parse(JSON.stringify(Object))来进行 缺点: 如果对象或者数组里有函数什么的, 就会出问题啦 ?
device-width, initial-scale=1.0"> Document 1234567891011// 在JS...// 当复杂类型实现浅拷贝,新对象与旧对象仍然同时指向堆内存的同一属性,互不独立,相互影响。..., // 也就是说当我们创建新数组newArr时,赋予newArr的是arr在栈中的地址(指针), // 其实仍与旧数组arr共享同一个内存,所以修改新数组newArr后,旧数组arr也会被修改// 深拷贝...// 它可以将复杂类型的数据相互独立出来,互不影响 // 深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型, // 这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据...2、 function deepClone(target) { // 定义一个变量 let result; // 如果当前需要深拷贝的是一个对象的话更多内容请见原文,原文转载自:http://www.mark-to-win.com
对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,而深复制则是开辟新的栈...,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。...深复制实现代码如下: 可以从两个方法进行解决。...,要想达到深复制就需要用递归 function deepCopy(o,c){ var c = c || {} for(var i in o){ if(typeof o[i...] === 'object'){ //要考虑深复制问题了 if(o[i].constructor === Array){
大家好,又见面了,我是你们的朋友全栈君。...如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
deepClone(value[key]); } return result; } return _deepClone(obj); } 三、ES6扩展运算符,一维对象则是深拷贝...,二维及以上则是浅拷贝。...四、JSON.stringify然后JSON.parse,如果是简单数据数据类型则可,如果value为date、null等,则会出现类型丢失情况,同时相对增加性能损耗问题(Object内的key、value...等类型都是在运行时确定的,所以stringify时需要很多工作要做)。
source=cloudtencent 以下主要介绍了正常情况下的拷贝、浅拷贝、深拷贝三种方式的区别。...正常拷贝:复制一个对象,它们的内存地址是相同的 浅拷贝:拷贝对象的第一层属性 深拷贝:拷贝对象多层的属性 正常拷贝 假设我们要复制一个对象,如果不对其进行深拷贝,那么改变其中一个对象后,另外一个对象也会跟着改变...,无论旧对象的属性有多少个,都可以自动拷贝到新的对象上。...以上方式由于是浅拷贝只能拷贝对象的一层属性,对于对象有多层属性依然是存在同样的问题。...b 的 children 属性改变后,对象 a 的 children 属性也会跟着改变,这也不是我们想要的效果,所以我们可以通过对象的深度拷贝实现(拷贝无限深的层级)。
说到深拷贝与浅拷贝,为什么会有这两种概念呢,根本原因就在于js的两种数据类型:基本数据类型和引用数据类型,两种数据类型存储方式不同。...JavaScript 中变量的拷贝 js 中的拷贝区分为「浅拷贝」与「深拷贝」。 浅拷贝 浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制,也就是说只会赋值目标对象的第一层属性。...深拷贝 深拷贝不同于浅拷贝,它不只拷贝目标对象的第一层属性,而是递归拷贝目标对象的所有属性。...() 和 Object.defineProperties() 方法; 字符串类型和 symbol 类型的属性都会被拷贝; 在属性拷贝过程中可能会产生异常,比如目标对象的某个只读属性和源对象的某个属性同名...JSON 进行忽略原型链的深拷贝 var dest = JSON.parse(JSON.stringify(target)); 同样的它也有缺点: 该方法会忽略掉值为 undefined 的属性以及函数表达式
因为对象是引用类型,所以赋值时的操作仅是赋予相同的地址,当对其中一个对象进行操作时,就会影响其他的对象。解决这个问题就需要使用拷贝了。...拷贝的方式分两种: 浅拷贝 基本类型:拷贝值 引用类型:拷贝对象引用。 深拷贝 基本类型:拷贝值 引用类型:会创建一个新的引用,将之前的对象完整的拷贝一份出来,并添加至新的引用当中。...这种比较试适合简单的单个数组或者对象使用,简单又方便 #深拷贝 #JSON.stringify() 如果要拷贝的对象中包含对象,就需要深拷贝了,一般使用原生的方法JSON.parse(JSON.stringify...RegExp) return new RegExp(obj); // 可能是对象或者普通的值 如果是函数的话是不需要深拷贝 if (typeof obj !...如何写出一个惊艳面试官的深拷贝?
); 使用JSON.parse(JSON.stringify(arr))的方式进行深拷贝时,并不会拷贝函数。...使用 JSON.parse(JSON.stringify(arr)) 进行深拷贝的方式相对简单且易于理解,适合用于处理普通的数据结构。...然而,它无法正确地处理一些特殊类型的数据,例如函数、正则表达式、日期对象等,因为这些类型在 JSON 格式中无法正确表示。 MessageChannel 使用MessageChannel实现深拷贝。...使用 MessageChannel 实现异步深拷贝,可以正确地处理任何类型的数据,包括特殊类型。 由于它是异步的方式,所以性能可能会受到一定影响,特别是在处理大型数据结构时会更明显。...) 是数组对象的一个方法,用于从数组中提取指定位置的元素创建一个新的数组。
——《赏荷》 对象深拷贝 export function deepClone (data) { var type = getObjType(data) var obj if (type
记一下js深拷贝的几种方法 使用递归 通过JSON对象 通过jQuery的extend方法 Object.assign() lodash函数 使用递归 //使用递归的方式实现数组、对象的深拷贝 function...deepClone(obj) { //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 var objClone = Array.isArray(obj)...//通过js的内置对象JSON来进行数组对象的深拷贝 function deepClone(obj) { var _obj = JSON.stringify(obj), objClone...= JSON.parse(_obj); return objClone; } tip: * 无法实现对对象中方法的深拷贝 通过jQuery的extend方法 var array = [1,2,3,4...]; var newArray = $.extend(true,[],array); Object.assign() 对象中只有一级属性,没有二级属性的时候,为深拷贝 对象中有对象的时候,在二级属性以后就是浅拷贝
然后面试中经常会问、业务中也经常会遇到的问题就是深浅拷贝的问题了。 栈内存中简单数据类型直接拷贝就能得到一个副本,但是复杂数据类型的拷贝如果也想得到一个副本,就需要深拷贝了。...这是因为: 数组、对象这类复杂类型数据结构,在栈内存里存放的只是指向堆内存中存放数据的地址, 你直接d = c; 拷贝的也是一个副本,但这个副本区别之处是,他并非数据的副本,而是栈内存地址的副本。...深拷贝 具体深拷贝就是要理解了复杂类型拷贝的缺点,然后再进行弥补。 既然想要复杂类型也像简单类型那样拷贝一个新数据的话,就不单单是拷贝地址了。...直接返回[object String]这样类型的。但其实在深拷贝阶段,直接将其放到object形式处理了。...如果循环过程中,数组中嵌套复杂类型,再次递归调用深拷贝方法。 对于对象,新建一个对象,然后for in遍历拷贝非原型值。如果循环过程中,对象中嵌套复杂类型,再次递归调用深拷贝方法。
1.区别: 深拷贝和浅拷贝的使用场景是在复杂对象里,即对象的属性还是对象; 浅拷贝是指只复制一层对象,当对象的属性是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化;深拷贝是指复制对象的所有层级...2.深拷贝实现 Json序列化与反序列化: function deepClone(obj){ let _obj = JSON.stringify(obj), objClone =...布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。...对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。...不可枚举的属性会被忽略 对于引用类型:object,array,date,regexp,function,err,只能深拷贝对象和数组,对于其他种类的对象,会失真。
/** * @param {oject} obj */ function deepClone(obj) { // obj 是 null ,或者不是对象和数组,直接返回 if (typeof
领取专属 10元无门槛券
手把手带您无忧上云