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

JavaScript深浅拷贝

深浅拷贝

基本类型和引用类型

  1. ECMAScript 中的变量类型分为两类:
  • 基本类型:undefined,null,布尔值(Boolean),字符串(String),数值(Number)
  • 引用类型: 统称为Object类型,细分的话,有:Object类型,Array类型,Date类型,Function类型等。
  1. 不同类型的存储方式:

基本数据类型 保存在 栈内存,形式如下:栈内存中分别存储着变量的标识符以及变量的值。

image

引用类型 保存在 堆内存 中, 栈内存存储的是变量的标识符以及对象在堆内存中的存储地址,当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从对应的堆内存中取得所需的数据。

image

对于仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响,为 浅拷贝。

而如果是在堆中重新分配内存,拥有不同的地址,但是值是一样的,复制后的对象与原来的对象是完全隔离,互不影响,为 深拷贝。

深浅拷贝 的主要区别就是:复制的是引用(地址)还是复制的是实例。

js的复制方法

slice和concat方法

var a = [[1,2,3],4,5];
var b = a.slice();
console.log(a === b);
a[0][0] = 6;
console.log(a);
console.log(b);

image

jQuery中的 extend 复制方法

var obj = {name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} };
var obj_extend = $.extend(true,{}, obj); //extend方法,第一个参数为true,为深拷贝,为false,或者没有为浅拷贝。
console.log(obj === obj_extend);
obj.company.name = "ali";
obj.name = "hei";
console.log(obj);
console.log(obj_extend);

image

Array 的 slice 和 concat 方法 和 jQuery 中的 extend 复制方法,他们都会复制第一层的值,对于 第一层 的值都是 深拷贝,而到 第二层 的时候 Array 的 slice 和 concat 方法就是 复制引用 ,jQuery 中的 extend 复制方法 则 取决于 你的 第一个参数, 也就是是否进行递归复制。

JSON 对象的 parse 和 stringify

JOSN 对象中的 stringify 可以把一个 js 对象序列化为一个 JSON 字符串,parse 可以把 JSON 字符串反序列化为一个 js 对象,这两个方法实现的是深拷贝。

var obj = {name:'xixi',age:20,company : { name : '腾讯', address : '深圳'} };
var obj_json = JSON.parse(JSON.stringify(obj));
console.log(obj === obj_json);
obj.company.name = "ali";
obj.name = "hei";
console.log(obj);
console.log(obj_json);

image

但是该方法也是有局限性的:

  • 会忽略 undefined
  • 不能序列化函数
  • 不能解决循环引用的对象

这个函数可以解决大部分问
题,并且该函数是内置函数中处理深拷贝性能最快的。如果你的数据中含有以上三种情况下,可以使用 lodash 的深拷贝函数。

当然,也可以利用递归自己封装深度克隆函数,

function deepClone(origin, target){
    var target = target || {},
         toStr = Object.prototype.toString,
         arrStr = "[object Array]";

    for(var prop in origin){
        if(origin[prop] !== 'null' && origin.hasOwnProperty(prop)){
            if(typeof(origin[prop]) === 'object') {
                target[prop] = toStr.call(origin[prop]) === arrStr ? [] : {};
                deepClone(origin[prop], target[prop]);
            }else{
                target[prop] = origin[prop];
            }
        }
    }
}

转载于:https://www.cnblogs.com/y-dt/p/9787506.html

相关文章:

  • 节约内存:Instagram的Redis实践
  • 智云大咖秀:怎样的稳定器才是摄影师的“灵魂辅助”?
  • Bootstrap vs Foundation如何选择靠谱前端框架
  • 双管齐下,VMware的容器新战略
  • 退役前的记录(2018.10.14-NOIP2018)
  • CENTOS 6.6 nfs 服务器搭建
  • JQuery Mobile难点备忘
  • C++语法小技巧
  • MeiTuanLocateCity仿美团城市列表选择界面
  • React Native安卓模拟器调出Dev Setting菜单
  • Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下
  • 少侠请重新来过 - Vue学习笔记(五) - 指令
  • AIX 系统 EBS form 打开报错FRM-92101: FORM server在启动过程中失败
  • JS面向对象编程
  • 解决Eclipse报errors running builder ‘javascript validator’ on project
  • CentOS6 编译安装 redis-3.2.3
  • CentOS7 安装JDK
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • Javascript设计模式学习之Observer(观察者)模式
  • MySQL用户中的%到底包不包括localhost?
  • Python学习之路16-使用API
  • Windows Containers 大冒险: 容器网络
  • 初探 Vue 生命周期和钩子函数
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 力扣(LeetCode)21
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 深入浅出Node.js
  • 一道面试题引发的“血案”
  • 正则与JS中的正则
  • 自制字幕遮挡器
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 我们雇佣了一只大猴子...
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (poj1.2.1)1970(筛选法模拟)
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (接口封装)
  • (九十四)函数和二维数组
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (原)本想说脏话,奈何已放下
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)Mysql的优化设置
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (转载)从 Java 代码到 Java 堆
  • .a文件和.so文件
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET 回调、接口回调、 委托
  • .NET程序员迈向卓越的必由之路
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • @Data注解的作用
  • @SuppressWarnings注解
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——