思路

首先是用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. 从 2018 年 Nacos 开源说起

    2018 年夏天 国内微服务开源 领域,迎来了一位新成员.此后,在构建微服务注册中心和配置中心的过程中,国内开发者多了一个可信赖的选项. Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务 ...

  2. 来电科技:基于Flink+Hologres的实时数仓演进之路

    简介: 本文将会讲述共享充电宝开创企业来电科技如何基于Flink+Hologres构建统一数据服务加速的实时数仓 作者:陈健新,来电科技数据仓库开发工程师,目前专注于负责来电科技大数据平台离线和实时架 ...

  3. [Contract] Solidity 合约发布到测试网 ropsten 的作用

    当我们本地完成了一系列测试以后,接下来就是准备上线了. 关于合约部署可以参考这篇:Solidity 合约使用 truffle 部署到测试网和主网 你可能有一个疑问,在上主网之前,先上测试网的作用是什么 ...

  4. [PHP] Laravel 依赖注入使用不当引起的内存溢出

    业务逻辑: 正常在 controller 方法的参数中注入某个类,方法中使用这个类时发生内存超出提示. 分析: 过往显示,正常使用依赖注入是不存在问题的,那么很有可能是哪里发生了循环引用,导致一直请求 ...

  5. MyBatis源码之MyBatis中SQL语句执行过程

    MyBatis源码之MyBatis中SQL语句执行过程 SQL执行入口 我们在使用MyBatis编程时有两种方式: 方式一代码如下: SqlSession sqlSession = sqlSessio ...

  6. Spring学习一(依赖注入/Bean/注解等)

    1.Spring依赖注入的方式. 2.依赖注入的类型 3.Bean的作用域 4.自动注入 5.使用注解的方式 6.在spring配置文件中引入属性文件 1.Spring依赖注入的方式 平常的java开 ...

  7. 10、操作系统安全加固-Linux加固

    1.账号管理与认证授权 1.1.为不同的管理员分配不同的账号 目的:根据不同用途设置不同账户账号,提高安全层级 实施方法: 1.设置高风险文件为最小权限,如:passwd.shadow.group.s ...

  8. go-admin开发小技巧

    搜索条件参考下面的文件 https://github.com/go-admin-team/go-admin-core/blob/master/tools/search/query_test.go ty ...

  9. 什么是NASM

    什么是NASM NASM是一个汇编器的名称,全称是Netwide Assembler,支持x86与x64架构的CPU(注意不支持ARM架构). 我们知道,在x86和x64架构上有多个操作系统,比较流行 ...

  10. SpringBoot-mybatis-plus 分页

    前言: 想必数据分页对于每一个程序员并不陌生,针对分页查询功能代码实现上:肯定是代码简洁明了且能达到分页的效果会更好! 现在我将基于SpringBoot - mybatisPlus分页查询的方法总结如 ...