思路

首先是用Object.prototype.toString.call(obj)来得到传入的值的类型,如果是几个基本类型,则直接返回值就可以了

如果是引用类型,则通过深拷贝函数递归进行再次拷贝。

注:也可以用constructor判断类型(参见deepClone2函数)

代码

/**
* 实现深拷贝
* @param {*} obj
* @returns {*} 拷贝完的对象
*/
function deepCopy(obj) {
let type = Object.prototype.toString.call(obj);
type = type.split(' ')[1].split(']')[0];
console.log(type);
if (type === 'Number') {
return obj;
} else if (type === 'Object') {
const new_obj = {};
for (item in obj) {
if (typeof item === 'object') {
new_obj[item] = deepCopy(item);
} else {
new_obj[item] = obj[item];
}
}
return new_obj;
} else if (type === 'Function') {
return obj;
} else if (type === 'String') {
return obj;
} else if (type === 'Boolean') {
return obj;
} else if (type === 'Array') {
const arr = [];
for (item of obj) {
if (typeof item === 'object') {
arr.push(deepCopy(item));
} else {
arr.push(item);
}
}
return arr;
} else if (type === 'Null') {
return null;
}
} const obj = {
a: 1,
b: {
bb: 1
},
d: [1, 2, { cc: '123' }]
} // const copy_obj = deepCopy(obj);
// console.log(obj === copy_obj)
// console.log(copy_obj);
// console.log(deepCopy(null))
/**
* 深拷贝优化版
*
* @param {*} source
* @returns {*}
*/
function deepClone2(source) {
let target;
console.log(source.constructor);
if (source.constructor === Array || source.constructor === Object) {
target = source.constructor === Array ? [] : {};
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (source[key] && typeof source[key] === 'object') {
target[key] = deepClone2(source[key]);
} else {
target[key] = source[key];
}
}
}
} else {
target = source;
}
return target;
} console.log(deepClone2(function () { }))
console.log(deepClone2([]))
console.log(deepClone2(1))
console.log(deepClone2(obj))

JavaScript通过递归实现深拷贝的更多相关文章

  1. 关于JavaScript的浅拷贝和深拷贝

    在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...

  2. javascript篇-浅拷贝与深拷贝

    理解javascript 的浅拷贝与深拷贝,首先看一下js的数据类型: js有5种基本数据类型:undefined,null,boolean,number,string 还有一种复杂的数据类型(也叫引 ...

  3. 全面聊聊JavaScript的浅拷贝和深拷贝

    一.背景      首先我们可以看下面这段简单的代码: var obj = {name:'程序猿',sex:'男'}; var arr = ['程序猿','程序媛']; var copyobj = o ...

  4. Javascript中递归造成的堆栈溢出及解决方案

    关于堆栈的溢出问题,在Javascript日常开发中很常见,Google了下,相关问题还是比较多的.本文旨在描述如何解决此类问题. 首先看一个实例(当然你可以使用更容易的方式实现,这里我们仅探讨递归) ...

  5. 每天一个JavaScript实例-递归实现反转数组字符串

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  6. 递归实现深拷贝( 只要学过js递归,看不懂找我包会 )

    要用递归实现深拷贝,首先说说什么是深拷贝和浅拷贝 浅拷贝:一个值赋给另一个值,当原先的值不改变地址的情况下改变数据,另一个值跟着变 深拷贝:一个值赋给另一个值,当原先的值不改变地址的情况下改变数据,另 ...

  7. javascript之闭包,递归,深拷贝

    闭包 理解:a函数执行后return出b函数且b函数可以访问a函数的数据 好处:子函数存储在复函数内部,子函数执行完不会被自动销毁 坏处:占用内存比较大 ex: function bibao(){ v ...

  8. JavaScript中浅拷贝和深拷贝的区别

    JavaScript数据类型 基础数据类型:保存在栈内存中的简单数据段 ,有undefined,boolean,number,string,null 引用数据类型:Array,object,Funct ...

  9. javascript的浅拷贝和深拷贝

    1.浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据. 2.深拷贝(复杂):复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制. 这里画一个简单的图来加深理解: ...

  10. JavaScript的递归之更多例子

    更多例子 第二个递归的例子是求两个自然数的最大公约数(有没有回到令人怀念的中学时代).下面的程序用的是经典的辗转相除法. //greatest common divisor //假定a.b都是正整数 ...

随机推荐

  1. 慢sql治理经典案例分享

    ​简介:菜鸟供应链金融慢sql治理已经有一段时间,自己负责的应用持续很长时间没有慢sql告警,现阶段在推进组内其他成员治理应用慢sql.这里把治理过程中的一些实践拿出来分享下. ​ 作者 | 如期 来 ...

  2. 揭秘!阿里实时数仓分布式事务Scale Out设计

    简介: Hybrid Transaction Analytical Processing(HTAP) 是著名信息技术咨询与分析公司Gartner在2014年提出的一个新的数据库系统定义,特指一类兼具O ...

  3. 6 张图带你彻底搞懂分布式事务 XA 模式

    简介: XA 协议是由 X/Open 组织提出的分布式事务处理规范,主要定义了事务管理器 TM 和局部资源管理器 RM 之间的接口.目前主流的数据库,比如 oracle.DB2 都是支持 XA 协议的 ...

  4. 鸿蒙HarmonyOS实战-ArkUI事件(触屏事件)

    前言 触屏事件是指通过触摸屏幕来进行操作和交互的事件.常见的触屏事件包括点击(tap).双击(double tap).长按(long press).滑动(swipe).拖动(drag)等.触屏事件通常 ...

  5. 11个Python循环技巧

    本文分享自华为云社区<Python中的循环技巧指南>,作者:柠檬味拥抱. 当我们处理数据时,有时候需要创建多个列表以存储不同类型或不同条件下的数据.在Python中,我们可以利用循环来快速 ...

  6. 2021年5.21NCU第四届校赛

    比赛地址:http://222.204.50.106/contest/39 A 树上祖先 链接:http://222.204.50.106/contest/39/problem/A B 莎士比亚 链接 ...

  7. 【GUI开发】用python爬YouTube博主信息,并开发成exe软件!

    目录 一.背景介绍 二.代码讲解 2.1 爬虫 2.2 tkinter界面 2.3 存日志 三.说明 一.背景介绍 你好,我是@马哥python说,一名10年程序猿. 最近我用python开发了一个G ...

  8. NSThread的main方法内部做了什么?

    NSThread当调用start方法的时候,start方法就会调用main方法.那么这个main方法内部做了什么呢?下面是汇编码: 1 ;Foundation`-[NSThread main]: 2 ...

  9. 密码学—DES加密的IP置换Python程序

    文章目录 IP初始置换与逆置换 编程想法 转二进制过程中的提取一些数据 64为一组 IP置换 IP逆置换 DES发明人 美国IBM公司W. Tuchman 和 C. Meyer1971-1972年研制 ...

  10. Linux/Golang/glibC系统调用

    Linux/Golang/glibC系统调用 本文主要通过分析Linux环境下Golang的系统调用,以此阐明整个流程 有时候涉略过多,反而遭到质疑~,写点文章证明自己实力也好 Golang系统调用 ...