JavaScript中浅拷贝和深拷贝的区别和实现
要理解 JavaScript中浅拷贝和深拷贝的区别,首先要明白JavaScript的数据类型
JavaScript有两种数据类型,基础数据类型和引用数据类型
基础数据类型:保存在栈内存中的简单数据段 ,有undefined,boolean,number,string,null
引用数据类型:Array,对象,Function 保存在堆内存空间中
a1 = 0;a2 = 'this is str';a3 = null 存放在栈内存中
var c =[1,2,3] 与 var d = {m:20} 变量名与内存地址存储在栈内存中,[1,2,3]与{m:20} 作为对象存储在堆内存中
基础数据类型的复制(如var a = 20 var b = a)
引用数据类型的复制 ( var m ={a:10, b:20} var n = m)
m与n指向同一个内存空间,当m或者n改变时,另一个也跟着改变
如m.a = 80 ; console.log(n.a) // 80
怎么样使引用数据类型有各自独立的内存空间
一、采用递归的方法复制拷贝对象
function deepclone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") {
for (key in obj) {
//if (obj.hasOwnProperty(key)) { //也可以不加
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepclone(obj[key])
} else {
objClone[key] = obj[key]
}
//}
}
}
return objClone
}
var a = [1, 2, 3, 4];
var b = deepclone(a);
a[0] = 8
console.log(a, b);
Array.isArray(obj):ECMAScript 5.1 (ECMA-262) 考虑到的兼容性,可以用下面的方法实现较好的兼容 if (!Array.isArray) { Array.isArray = function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; }
二、用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
function deepclone(obj){
var _obj = JSON.stringify(obj);
var cloneObj = JSON.parse(_obj);
return cloneObj
}
var a =[1,2,3,4];
var b= deepclone(a);
a[0]=8
console.log(a,b);
//可以用JSON.stringify与JSON.parse实现深拷贝的原因是JSON.stringify(obj)转换成字符串,变成基本数据类型,基本类型拷贝是直接在栈内存新开空间,直接复制一份名-值,不影响之前的对象
总结:
**浅拷贝(shallow copy):只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存; **
深拷贝(deep copy):复制并创建一个一摸一样的对象,不共享内存,修改新对象,旧对象保持不变;实现深拷贝主要有2种方法
(1)递归
(2)JSON.stringify结合JSON.parse
- SQL优化二(SQL性能调优)
- database replay基础学习(r4笔记第90天)
- Vivotek 摄像头远程栈溢出漏洞分析及利用
- 03.HTML头部/CSS/图像/表格/列表
- 巧用flashback database实现灵活的数据切换(r5笔记第9天)
- 01.HTML教程/简介/基础
- 大型分布式网站架构技术总结
- MySQL和Oracle对比之存储过程(r5笔记第7天)
- 07.Java变量类型
- OAuth 2.0验证【面试+工作】
- MySQL备份恢复第一篇(r5笔记第5天)
- 经典面试问题: Top K 之 -- 海量数据找出现次数最多或,不重复的
- Java多线程详解4【面试+工作】
- Java多线程详解5【面试+工作】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 浅谈vue+element全局loading加载
- LeetCode59|重复N次的元素
- 谈Vue组件的is特性
- 基于日志的回放对比系统设计
- 【收藏向】常用Java排错工具单
- MYSQL数据同步之基于GTID事务数据同步
- 【风险通告】XXL-JOB远程命令执行漏洞
- MySQL8.0特性之redo logging动态开关
- 3分钟短文:Laravel模型集合跟基类真不一样,别混为一谈
- 3分钟短文:Laravel模型一对一一对多关系真的乱吗?
- 3分钟短文:Laravel请求对象方法极多,可不是花拳绣腿
- 3分钟短文:Laravel验证用户输入,不要把啥都存到系统里
- 3分钟短文:Laravel用户自定义命令行简明教程
- 3分钟短文:Laravel命令行参数和可选项分不清?怎么可能!
- 《Offer一箩筐》求职之前你必须知道的 4 件事!!