JS数据类型可以分为(ES5,暂时不考虑ES6):

  简单数据类型:Number、String、undefined、boolean

  复杂数据类型:Object、Array

简单的数据类型,往往是赋值操作,而复杂数据类型是引用操作。

赋值操作我们就不讲了,主要看看引用操作把

    var arr = [1,2,3];
var arr2 = arr;
arr2.push(4);
console.log(arr);//输出[1,2,3,4]

明明是对arr2进行的操作,为什么arr也变化了呢?因为js存储对象都是存地址的,所以arr2实际存储的是:"arr在内存中的地址";

由此我们可以明白,既然都是指向同一个内存地址,当我们改变任何一个的时候,都会改变。

知道这个基本的特性那么我们可以试图来理解下浅复制和深复制

首先看一段代码,我们再来讲解下概念

    var obj ={a:1,b:2,c:[1,2]};
var shallowCopy = shallow(obj);
function shallow(obj){
var shallowObj = {};
for(var name in obj){
if(obj.hasOwnProperty(name)){
shallowObj[name] = obj[name]
}
}
return shallowObj
}
console.log(shallowCopy);//输出的就是这个对象,我们实现了简单的浅复制;

浅复制:只会将对象的各个属性进行依次复制,并不会进行递归复制,而js存储对象都是存地址的,所以浅复制会导致obj.c和shallowCopy.c 指向同一块内存地址;会导致引用。

深复制:它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在上面obj和shallowCopy的c属性指向同一个对象的问题。(待会贴出深复制的代码,这是个复杂的问题)

总结:需要注意的是,如果对象比较大,层级也比较多,深复制会带来性能上的问题。在遇到需要采用深复制的场景时,可以考虑有没有其他替代方案,在实际的引用场景中,也是浅复制更为常用。

我现在给出一个简单版本的深复制,可以复制对象和数组(不考虑循环引用问题,函数对象问题),如果想深入研究的话可以看下这篇文章:http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/

在这里我们只理解思想和简单的实现,实际项目中可以考虑使用lodash(http://lodashjs.com/docs/),或者jQuery的extend的方法也同样可以

    function deepClone(obj){
var newObj = obj.constructor === Array ? []:{};
if(typeof obj !== 'object'){
return
}else{
for(var i in obj){
if(obj.hasOwnProperty(i)){
newObj[i] = typeof obj[i] === 'object'?deepClone(obj[i]):obj[i];
}
}
}
return newObj
}

最核心的思想还是采用递归的方式,不断进行,直到基本数据类型后,再复制

方法还有很多种,譬如还有使用JSON.stringify进行序列化,JSON.parse进行反序列化,实现"偷懒版"的深复制...等等

js对象的深浅拷贝的更多相关文章

  1. js中的深浅拷贝

    js中的深浅拷贝 js中有深拷贝.浅拷贝一说,所谓的深浅拷贝是针对value类型为引用类型(函数.对象.数组)而言的,大概理解的就是: 浅拷贝: 拷贝出的对象c和原始对象o,c和o在key对应的val ...

  2. 关于Java的Object.clone()方法与对象的深浅拷贝

    文章同步更新在个人博客:关于Java的Object.clone()方法与对象的深浅拷贝 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Object.clon ...

  3. 【 js 基础 】 深浅拷贝

    underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...

  4. JS复习之深浅拷贝

    一.复习导论(数据类型相关) 想掌握JS的深浅拷贝,首先来回顾一下JS的数据类型,JS中数据类型分为基本数据类型和引用数据类型. 基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以 ...

  5. 超实用的JavaScript代码段 Item8 -- js对象的(深)拷贝

    js 对象 浅拷贝 和 深拷贝 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = { nation:'中国' } var Doctor ...

  6. Object.clone()方法与对象的深浅拷贝

    转载:[https://www.cnblogs.com/nickhan/p/8569329.html] 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理.这时候就可以用到Java中的Obj ...

  7. js对象的深度拷贝

    //判断对象的类型 Array Object Function String Number ..... function getObjType(obj){ return Object.prototyp ...

  8. 总结JavaScript对象的深浅拷贝

    十四.对象的浅拷贝与深拷贝 什么是对象的拷贝? 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝 什么是深拷贝, 什么是浅拷贝? 我们假设将A对象赋值给B对象 浅拷贝是指, 修改B对象的属性和方法 ...

  9. js对象深潜拷贝(从requirejs中抠出来的)

    var op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty; function isFunction(it ...

随机推荐

  1. struts2中常用constant命令配置

    struts.objectFactory这个属性用 于说明Struts2的 对象池创建工厂,Struts2也有自己的对象池,就像Spring那样,在配置文件中你可以引用对象池中的对象,你可以借助于Sp ...

  2. kubernetes 学习 创建cronjob

    POM.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  3. JAVA web 相关知识点

    1: web的三个核心标准: URL: http   VS  https HTTP:  通信协议,客户端/服务器端信息交互方式; 特点是无状态:                 HTML: 2: HT ...

  4. Windows_Server_2008远程桌面多用户登陆的配置方法

    开启远程桌面后,Windows Vista(或Windows 2008)下默认只支持一个administrator用户登陆,一个登录后另一个就被踢掉了,下面提供允许同一个用户名同时多个用户登录的配置方 ...

  5. NBU客户端备份失败,报错error 48 client hostname could not be found

    今天在做备份时发现了这个报错.经过ping, nslookup, bpclntcmd命令检查没有发现连接或域名解析存在问题. 参考文档http://www.symantec.com/docs/TECH ...

  6. javascript——对象的基础知识

    一.javascript作为脚本语言可以完成以下任务: 操纵浏览器对象,如窗口的打开与关闭: 操纵Dom树: 通过XMLHttpRequest对象与服务器端进行异步通信: XML编程,借助于Activ ...

  7. 蓝牙服务 UUID

    https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx 手机蓝牙对手机 ,华为平板取红米手机 8 个Audio So ...

  8. C#封装CRUD到SqlHelper类解读

    1.简单说明一下,一般情况下,数据库连接字符串是在App.config文件中进行配置,然后再在代码中进行引用.因此,我们在这里先看一下App.config文件. 首先看需要添加的内容: 参数说明: n ...

  9. App.CSharp.Grid的ICells接口

    using System;using System.Collections.Generic;using System.Text;using System.Drawing;using System.Wi ...

  10. c++primer-p101.ex3.24

    要求使用迭代器 读入一组整数并把它们存入一个vector对象 1. 将相邻每对整数和输出 2. 先输出第一个和最后一个数的和,然后是第二个和倒数第二个...等等 自己写的: #include<i ...