深浅拷贝

基本类型和引用类型

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

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

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

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

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

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

js的复制方法

slice和concat方法

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

jQuery中的 extend 复制方法

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

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

JSON 对象的 parse 和 stringify

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

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

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

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

这个函数可以解决大部分问

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

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

  1. function deepClone(origin, target){
  2. var target = target || {},
  3. toStr = Object.prototype.toString,
  4. arrStr = "[object Array]";
  5. for(var prop in origin){
  6. if(origin[prop] !== 'null' && origin.hasOwnProperty(prop)){
  7. if(typeof(origin[prop]) === 'object') {
  8. target[prop] = toStr.call(origin[prop]) === arrStr ? [] : {};
  9. deepClone(origin[prop], target[prop]);
  10. }else{
  11. target[prop] = origin[prop];
  12. }
  13. }
  14. }
  15. }

JavaScript深浅拷贝的更多相关文章

  1. JavaScript深浅拷贝区别

    分享一篇自己关注的微信订阅号(前端大全)文章:JavaScript浅拷贝与深拷贝 作者:浪里行舟 https://github.com/ljianshu/Blog/issues/5 这里很详细的讲解了 ...

  2. JavaScript 深浅拷贝

    JavaScript有五种基本数据类型(Undefined, null, Boolean, String, Number),还有一种复杂的数据类型,就是对象. Undefined 其实是已声明但没有赋 ...

  3. 谈谈JavaScript深浅拷贝

    浅拷贝 function shallowCopy(source){ var newObj = {}; for(var attr in source){ newObj[attr] = source[at ...

  4. javascript简单实现深浅拷贝

    深浅拷贝知识在我们的日常开发中还算是用的比较多,但是之前的状态一直都是只曾听闻,未曾使用(其实用了只是自己没有意识到),所以今天来跟大家聊一聊js的深浅拷贝: 首先我们来了解一下javascript的 ...

  5. JavaScript数据存储和深浅拷贝实际运用

    JavaScript分两种数据类型.1.简单数据类型有:number, string, boolean, undefined和null当声明一个简单数据类型的变量时,在内存中会把数据存在栈里.2.复杂 ...

  6. JavaScript中的事件委托机制跟深浅拷贝

    今天聊下JavaScript中的事件委托跟深浅拷贝 事件委托 首先呢,介绍一下事件绑定 //方法一:通过onclick <button onclick="clickEvent()&qu ...

  7. javascript实现深浅拷贝

    深浅拷贝通常是对于引用数据类型进行的(数据类型为:对象(Object).数组(Array).函数(Function)) 浅拷贝: let obj = {id: 1, name: 2}; let new ...

  8. Javascript 中的深浅拷贝

    工作中经常会遇到需要复制 JS 数据的时候,遇到 bug 时实在令人头疼:面试中也经常会被问到如何实现一个数据的深浅拷贝,但是你对其中的原理清晰吗?一起来看一下吧! 为什么会有深浅拷贝 想要更加透彻的 ...

  9. JavaScript中的深浅拷贝

    深浅拷贝 在JS中,数据类型分为两类: ​ 简单数据类型:Number.Boolean.String.undefined ​ 引用数据类型:Array.Object.Function 简单数据类型通常 ...

随机推荐

  1. Git安全配置

      今天收到了阿里云异地登录的短信报警,登录阿里云后台发现,有人从深圳登录了我的服务器(本人在北京),查看详细信息一共登录了5次,前两次是使用的git用户进行登录,后两次已经变成了root用户,怀疑是 ...

  2. Google Summer of Code礼包

    这个暑假参加google summer of code, 给Google的分布式容器管理系统kubernates开发新的特性,希望从中学习更多的分布式的技术,锻炼自己的编程技巧. 中午在学校的图书馆吗 ...

  3. fleet中service之间的依赖关系

    最近有人在topcoder上提出使用fleet在集群上部署service时有时候会发现,当启动依赖于整个集群服务的service时,只会检查那个service所在机器的依赖关系,这样就会造成一些问题, ...

  4. 解决 Eclipse Indigo 3.7、ADT 中文字体偏小,完美 Consolas 微软雅黑混合字体!

    Eclipse是著名的跨平台的自由集成开发环境(IDE).6月22日Eclipse 3.7 正式发布,代号是 Indigo . 在 Windows 7 下初始后化,发现界面变化不大,但中文字体却面目全 ...

  5. 1.WebApi介绍

    1.WebApi是什么: WebAPI 是一种用来开发系统间接口.设备接口 API 的技术,基于 Http 协议,请求和返 回格式结果默认是 json 格式.比 WCF 更简单.更通用,比 WebSe ...

  6. C# 二维码/条形码入门操作

    效果图: 先给之前的群友道个歉,说声不好意思.QRCoder 只支持二维码,没有条形码. 以上demo生成条形码是用 BarcodeLib 这个库,识别是用 zxing,二维码生成用 QRCoder, ...

  7. c# WPF客户端调用WebAPI并转换成List

    利用HttpClient.JsonConvert实现. 引用Newtonsoft.Json.dll和System.Net.Http. 举个例子:从webapi中获取设备列表. public parti ...

  8. .net下使用最小堆实现TopN算法

    测试代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac ...

  9. Mysql 练习题一

    库操作: 1. 创建 数据库  create database db1; 2. 使用数据库 use db1 3. 查看表  show tables; 4. 删除  drop database db1  ...

  10. ubuntu14.0 安装 node v8.11.1(任意版本)

    由于众所周知的原因,通过node官网下载速度十分慢,我这里通过淘宝镜像安装 node8.11.1,其他版本同理. node版本淘宝镜像地址:https://npm.taobao.org/mirrors ...