当前位置: 首页 > news >正文

js实现深拷贝

展开运算符...和Object.assign都是浅拷贝,常见的js方法如slice也是浅拷贝,那如何实现深拷贝呢?

// 需要递归拷贝 
function deepClone(obj) {
  // 如果传递的是null 那就不处理
  // 函数没有引用关系
  if (typeof obj !== 'object') return obj;
  if (obj == null) return null;
  // 处理日期和正则
  if (obj instanceof RegExp) return new RegExp(obj);
  if (obj instanceof Date) return new Date(obj);
   // Object.prototype.toString.call(obj) === '[object Array]', 这么判断保留不了继承关系
  let instance = new obj.constructor(); // 看当前实例的constructor
  // 实现深拷贝
  //for...in循环是 遍历对象的每一个可枚举属性,包括原型链上面的可枚举属性,
   for (let key in obj) {
            if(obj.hasOwnProperty(obj[key])) {
                instance[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
            }
        }
  return instance;
}
// 函数不需要重新拷贝
let obj = { a: { a: 1 } }
let newObj = deepClone(obj);
obj.a.a = 2;
console.log(newObj);

复制代码

思路是首先判断obj类型,null、Date对象,数组、正则、以及对象的typeof结果都是oobject, 需要单独分情况考虑。 对于null、Date对象以及正则,我们直接返回数值就可以了 对于数组,我们没有直接返回,因为数组可能有继承关系,需要保留继承关系,这个需要注意。 1)判断数组类型我们没用Object.prototype.toString.call(obj),因为它保留不了继承关系。 举例如下:

var t = [1,2]
t.__proto__={a:1}
Object.prototype.toString.call(t) ----> // "[object Array]"
t.constructor ----->  // ƒ Object() { [native code] }
new t.constructor() --> objcet

复制代码

补充一下instanceof f instanceof Foo判断逻辑是: f的__proto__一层一层往上,能否对应到Foo.prototype

转载于:https://juejin.im/post/5b095879f265da0dc9244a05

相关文章:

  • [转载]我再也不想在任何头文件中看到“using namespace xxx;”了
  • Mybatis架构设计及源码分析-SqlSession
  • C# 禁止windows程序重复运行的两种基本方法
  • 代码动态设置edittext输入类型为密码类型
  • 用ASDF来组织Lisp程序编译和加载
  • TensorFlow与OpenCV,读取图片,进行简单操作并显示
  • 移动终端开发必备知识
  • MAC配置环境变量
  • oracle的nvl和sql server的isnull
  • UTC时间与当地时间的转换关系?
  • oracle分页查询
  • 做项目学习Django2.0开发
  • [转]虚拟机下Ubuntu共享主机文件(Ubuntu、VMware、共享)
  • js中clientHeight,offsetHeight,scrollHeight的区别
  • Range Slider With Progress
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 0基础学习移动端适配
  • Facebook AccountKit 接入的坑点
  • iOS 系统授权开发
  • JS笔记四:作用域、变量(函数)提升
  • nginx 负载服务器优化
  • nodejs:开发并发布一个nodejs包
  • RxJS: 简单入门
  • session共享问题解决方案
  • STAR法则
  • 阿里云前端周刊 - 第 26 期
  • 大主子表关联的性能优化方法
  • 计算机在识别图像时“看到”了什么?
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  •  一套莫尔斯电报听写、翻译系统
  • Android开发者必备:推荐一款助力开发的开源APP
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​queue --- 一个同步的队列类​
  • #Linux(Source Insight安装及工程建立)
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (一)RocketMQ初步认识
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转) RFS+AutoItLibrary测试web对话框
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • ..回顾17,展望18
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET Core 2.1路线图
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net中调用windows performance记录性能信息
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • [100天算法】-二叉树剪枝(day 48)
  • [20170705]diff比较执行结果的内容.txt