20190311期深拷贝与浅拷贝的区别?如何实现一个深拷贝在回答这个问题前,我们先来回顾一下JS中两大数据类型基本类型 Undefined、Null、Boolean、Number、String引用类型 Object Array基本类型基本类型就是值类型, 存放在栈(stack)内存中的简单数据段,数据大小确定,内存空间大小可以分配引用类型引用类型, 存放在堆(heap)内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置根据上面的分析,我们分别是两处类型做一个copy处理let obj = { name: ‘每日一题’, value: ‘JS’}let obj2 = objlet obj3 = obj.nameconsole.log(obj2.value) //JSconsole.log(obj3) // 每日一题// 改变obj2,obj3obj2.value = ‘CSS’obj3 = ‘HTML’console.log(obj.value) // CSSconsole.log(obj.name) // 每日一题从上面的输出结束来看,我们可以猜测obj,obj2操作的是同一个对象,而obj和obj3是完全独立的, 说到这里就进入了深浅拷贝浅拷贝概念: 对于字符串类型,浅拷贝是对值的复制,对于对象来说,浅拷贝是对对象地址的复制, 也就是拷贝的结果是两个对象指向同一个地址基本概念回过头去看上面的代码我们就能分析出来其都是浅复制深拷贝概念: 深拷贝开辟一个新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性如何实现深拷贝JSON.stringify()首先安利一个无脑黑科技骚操作 * 缺点: JSON.stringify()无法正确处理函数let obj = { name: ‘每日一题’, value: ‘JS’}console.log(JSON.parse(JSON.stringify(obj))) // 深拷贝了一份objlet obj = { name: ‘每日一题’, value: ‘JS’, fn: function(){}}console.log(JSON.parse(JSON.stringify(obj))) // obj.fn 丢失递归讲到深copy很多人都会想到extend方法,没错,这玩意deep为true确实能深copy,我们就过来翻一翻他的源码这边以大家熟悉的jquery为例// 源码地址 https://github.com/jquery/jquery/blob/5bdc85b82b84e5459462ddad9002f22d1ce74f21/src/core.js#L125// 只取核心逻辑代码,感兴趣的可以自行去源码地址查看具体实现// 有英文注释,我就不蹩脚翻译了// 整体思路就是递归对象,判断类型,处理类型 for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we’re merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { src = target[ name ]; // Ensure proper type for the source value if ( copyIsArray && !Array.isArray( src ) ) { clone = []; } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { clone = {}; } else { clone = src; } copyIsArray = false; // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don’t bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } }总结浅拷贝是复制,两个对象指向同一个地址深拷贝是新开栈,两个对象指向不同的地址关于JS每日一题JS每日一题可以看成是一个语音答题社区 每天利用碎片时间采用60秒内的语音形式来完成当天的考题 群主在次日0点推送当天的参考答案注 绝不仅限于完成当天任务,更多是查漏补缺,学习群内其它同学优秀的答题思路点击加入答题