博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js对象的深拷贝,你真的觉得很简单吗?
阅读量:3888 次
发布时间:2019-05-23

本文共 3090 字,大约阅读时间需要 10 分钟。

1.如何实现深拷贝?

1.简单粗暴使用JSON.parse(JSON.stringify(obj))
  • 存在的问题:不支持函数和正则等拷贝。
let obj = {
name: 'ha', friends: {
name: 'zj', parent: {
name: 'parent' } }, score: [ 1, 2, 3 ], getName: function () {
return this.name; }, reg: /\w/g } const obj_2 = JSON.parse(JSON.stringify(obj)); obj_2.friends.parent.name = 12121212; obj_2.score.push('ja'); console.log('obj_2==', obj_2); console.log('obj==', obj);

结果如下:

在这里插入图片描述

2.循环递归
  • 实现如下:
// 自己实现一个对象的深拷贝function deepClone(sourceObj) {
if (typeof sourceObj !== 'object' || sourceObj === null) return sourceObj; const cloneObj = {
} for (let key in sourceObj) {
// for...in 会遍历对象自身的和继承的可枚举的属性。 if (sourceObj.hasOwnProperty(key)) {
// 只拷贝对象自身的属性 if (typeof sourceObj[key] !== 'object'){
// 这里分为两种:1.基本类型,2.函数(我觉得无法对函数进行深拷贝了) cloneObj[key] = sourceObj[key]; } else {
// 这里分为两种:1.数组,2.对象 ,3.正则(正则这里,我暂时不清楚如何深拷贝,哈哈) !sourceObj[key].forEach ? (Object.prototype.toString.call(sourceObj[key]) !== '[object RegExp]' ? cloneObj[key] = deepClone(sourceObj[key]) : cloneObj[key] = sourceObj[key]) : cloneObj[key] = [...sourceObj[key]]; } } } return cloneObj;}

判断一个引用类型的变量是数组,对象还是正则。用instanceof或者Object.prototype.toString.call(obj)

instanceof判断的具体代码为:

if (typeof obj === 'object') {
if (obj instanceof Array) {
// 为数组 } else (obj instanceof RegExp) {
// 为正则 } else {
// 为对象 }}
  • 上面方式存在的问题:
    循环引用,即会死循环,导致爆栈。
var obj = {
name: 'ha', friends: {
name: 'zj', parent: {
name: 'parent' } }, score: [ 1, 2, 3 ], getName: function () {
return this.name; } } obj.issue = obj;

调用deepClone(obj)后,出现如下结果。栈溢出

在这里插入图片描述

  • 那么如何解决呢?
    思路:可以开辟一个数组,用来存储已经拷贝的对象,然后,每次拷贝之前,进行判断该对象是否已经拷贝过即可。
const hadDeepClone = []; // 存储已经拷贝过的引用类型值function deepClone(sourceObj) {
if (typeof sourceObj !== 'object') return sourceObj; if (hadDeepClone.includes(sourceObj)) {
return; } else{
hadDeepClone.push(sourceObj); } const cloneObj = {
} for (let key in sourceObj) {
// for...in 会遍历对象自身的和继承的可枚举的属性。 if (sourceObj.hasOwnProperty(key)) {
// 只拷贝对象自身的属性 if (typeof sourceObj[key] !== 'object'){
// 这里分为两种:1.基本类型,2.函数(我觉得无法对函数进行深拷贝了) cloneObj[key] = sourceObj[key]; } else {
// 这里分为两种:1.数组,2.对象 ,3.正则(正则这里,我暂时不清楚如何深拷贝,哈哈) !sourceObj[key].forEach ? (Object.prototype.toString.call(sourceObj[key]) !== '[object RegExp]' ? cloneObj[key] = deepClone(sourceObj[key]) : cloneObj[key] = sourceObj[key]) : cloneObj[key] = [...sourceObj[key]]; } } } return cloneObj;}

结果如下:

在这里插入图片描述

转载地址:http://jwxhn.baihongyu.com/

你可能感兴趣的文章
SVN更新失败 解决方法
查看>>
关于Java的File.separator
查看>>
linux定时任务的设置
查看>>
MySQL 5.7 完全傻瓜安装教程 图文
查看>>
Hibernate框架概述&SSH框架工作原理以及流程
查看>>
Aapche POI txt 导入excel
查看>>
C语言 ## __VA_ARGS__ 宏
查看>>
C++项目中的extern "C" {}
查看>>
(转)C++中extern “C”含义深层探索
查看>>
【日常小记】linux中强大且常用命令:find、grep
查看>>
Linux多线程编程(不限Linux)
查看>>
C/C++内存泄漏及检测
查看>>
C中的继承和多态
查看>>
linux修改ssh端口和禁止root远程登陆设置
查看>>
What really happens when you navigate to a URL
查看>>
偶遇with ties
查看>>
linux 编译指定库、头文件的路径问题
查看>>
使用gdb调试运行时的程序小技巧
查看>>
linux后端服务程序之信号处理
查看>>
Padding也要小心
查看>>