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

JS对象的克隆

在JS中一切都是对象,分为原始类型和合成类型:

原始类型:Undefined、Null、Boolean、String、Number,按值传递

合成类型:array、object和function,按内存中的地址传递。

浅克隆:基本类型按值传递,对象是引用传递;

深克隆:所有元素或属性均完全克隆,并于原引用类型完全独立,即,在后面修改对象的属性的时候,原对象不会被修改。

Object.assign, JSON.stringifyJSON.parse 方法去克隆一个对象,这个可以明确告诉大家这些都是些不靠谱的浅度克隆。

一:Object.assign()

Object.assign方法用于对象的合并,将源对象( source )的所有可枚举属性,复制到目标对象( target )。

Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。

Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

var x = {
  a: 1,
  b: { f: { g: 1 } },
  c: [ 1, 2, 3 ]
};
var y = Object.assign({}, x);
console.log(y.b.f === x.b.f);     // true复制代码

二:JSON对象的parse和stringify

//例1
var source = { name:"source", child:{ name:"child" } } 
var target = JSON.parse(JSON.stringify(source));
target.name = "target";  //改变target的name属性
console.log(source.name); //source 
console.log(target.name); //target
target.child.name = "target child"; //改变target的child 
console.log(source.child.name); //child 
console.log(target.child.name); //target child
//例2
var source = { name:function(){console.log(1);}, child:{ name:"child" } } 
var target = JSON.parse(JSON.stringify(source));
console.log(target.name); //undefined
//例3
var source = { name:function(){console.log(1);}, child:new RegExp("e") }
var target = JSON.parse(JSON.stringify(source));
console.log(target.name); //undefined
console.log(target.child); //Object {}
复制代码

这种方法使用较为简单,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。还有一点不好的地方是它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。同时如果对象中存在循环引用的情况也无法正确处理。


浅克隆

function shallowClone(obj){
    let tmp = {};
    for(let i in obj){
        tmp[i] = obj[i];
    }
    return tmp;
}复制代码

深克隆

function deepClone(obj) {
    if(typeof obj !== 'object' && typeof obj !== 'function'){
        return obj;
    }
    var tmp = Array.isArray(obj) ? []:{};
    for(let i in obj){
        if(obj.hasOwnProperty(i)){
            tmp[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i];
         }
    }
    return tmp;
}复制代码


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

相关文章:

  • 作为面试官如何从深度和广度上考察面试者
  • 沃森想通过社交网络筛出最想要优惠券的人
  • 刨根问底 | Elasticsearch 5.X集群多节点角色配置深入详解【转】
  • 在word中输入任意角度旋转图片
  • python怎么写可读性好的面向过程的长篇代码?
  • 第一节:.Net版基于WebSocket的聊天室样例
  • Leetcode 28 实现strStr()
  • 小程序开发之改变data中数组或对象的某一属性值
  • 跟鱼八学NDK开发 基于Cmake(三) 使用含有第三方动态库的自己编译好的.so
  • MVC-Model数据注解(三)-Remote验证的一个注意事项
  • Go语言编写的web管理平台生成框架
  • 如何对高管实施股权激励?
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • PhotoShop制作gif动态广告效果示例
  • 怎样轻松将SD卡照片数据恢复
  • C语言笔记(第一章:C语言编程)
  • ECMAScript6(0):ES6简明参考手册
  • HTTP那些事
  • JWT究竟是什么呢?
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • MobX
  • mysql中InnoDB引擎中页的概念
  • October CMS - 快速入门 9 Images And Galleries
  • Sass 快速入门教程
  • Tornado学习笔记(1)
  • vue-cli3搭建项目
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 订阅Forge Viewer所有的事件
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 检测对象或数组
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 三栏布局总结
  • 使用Gradle第一次构建Java程序
  • 使用权重正则化较少模型过拟合
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (C++17) std算法之执行策略 execution
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十)T检验-第一部分
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET Core 项目指定SDK版本
  • .NET Core引入性能分析引导优化
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .Net7 环境安装配置
  • .NET中winform传递参数至Url并获得返回值或文件