最简js深浅拷贝说明
1.浅拷贝
浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。
浅拷贝分两种情况:
1、直接拷贝源对象的引用
2、 源对象拷贝实例,但其属性对象(类型为Object,Array的属性)拷贝引用
直接拷贝源对象的引用
//最简单的例子
var a = {c:1};
var b = a;
console.log(a === b); // 输出true。
a.c = ;
console.log(b.c); // 输出 2,,这里就是拷贝了对象的引用,从而两边都改变了
源对象拷贝实例,其属性对象拷贝引用
说明:外层源对象是拷贝实例,当其属性元素为复杂数据类型时,内层元素拷贝引用。这时对源对象直接操作,不影响两对象,但是对其属性操作时候,会改变两对象的属性的值。
常用方法为:Array.prototype.slice(), Array.prototype.concat(), jQury的$.extend({},obj)
var a = [{c:1}, {d:2},2];
var b = a.slice();
console.log(a === b); // 输出false,说明外层数组拷贝的是实例
a[].c = ;
console.log(b[].c); // 输出 3,说明其元素拷贝的是引用
a[2]=4;
console.log(b[2]); //输出 2,不是复杂数据类型,所以没有变,没有引用
2.深拷贝
将重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响。
深拷贝
说明:深拷贝后,两个对象,包括其内部的元素互不干扰。常见方法有JSON.parse(),JSON.stringify(),jQury的$.extend(true,{},obj):
b = JSON.parse( JSON.stringify(a) )//最简单的深拷贝
但有局限性:
- 无法复制函数
- 原型链没了,对象就是object,所属的类没了
jQury的$.extend(true,{},obj):
var a = {c: {d: }};
var b = $.extend(true, {}, a);
console.log(a === b); // 输出false
a.c.d = ;
console.log(b.c.d); // 输出 1,没有改变。
深拷贝本质理解:将原对象各个属性所包含的对象也依次采用深复制的方法“递归复制”到新对象上。这就不会存在上面 obj 和 shadowObj 的 arr 属性指向同一个对象的问题。例:
var deepCopy= function(source) {
var result={};
for (var key in source) {
result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];
}
return result;
}//通过递归调用复制对对象上的每一个子类进行复制,从而达到时属性指向不同对象
复杂全面的代码,可以学习借鉴
function() {
function _type(value) {
return Object.prototype.toString.call(value).slice().slice(, -).toLowerCase();
}
function isArray(value) {
return _type(value) == 'array';
}
function isObject(value) {
return _type(value) == 'object';
}
function cloneArray(src, dest) {
src.forEach(function(item, index) {
if (isArray(item)) {
console.log('yes')
dest[index] = [];
copy(src[index], dest[index]);
} else {
dest[index] = src[index];
}
});
}
function cloneObject(src, dest) {
for (var key in src) {
// filter 原型链上面的属性
if (src.hasOwnProperty(key)) {
if (isObject(src[key])) {
// 判断循环引用的问题
if (src[key] === src) {
dest[key] = src;
} else {
dest[key] = {};
copy(src[key], dest[key]);
}
} else if (isArray(src[key])) {
dest[key] = [];
cloneArray(src[key], dest[key])
} else {
dest[key] = src[key];
}
}
}
}
function cloneDeep(src) {
if (isArray(src)) {
var dest = [];
cloneArray(src, dest);
}
if (isObject(src)) {
var dest = {};
cloneObject(src, dest);
}
return dest;
}
window.clone = cloneDeep;
})();
如有错误欢迎留言改正……
最简js深浅拷贝说明的更多相关文章
- js 深浅拷贝 笔记总结
一.js 数据类型 javaScritp的数据类型有:数值类型.字符串类型.布尔类型.null.undefined.对象(数组.正则表达式.日期.函数),大致分成两种:基本数据类型和引用数据类型, 其 ...
- JS深浅拷贝及其实现
基本数据类型和引用数据类型 JS数据分为基本数据类型和引用数据类型.基本数据类型的变量存储在栈中,引用数据类型则存储在堆中,引用数据类型的存储地址则保存在栈中. 下面来看一个小例子 // 基本数据类型 ...
- jQuery开发插件的两个方法 js 深浅拷贝
1.jQuery.extend(object);为扩展jQuery类本身.为类添加新的方法.由全局函数来调用, 主要是用来拓展个全局函数 2.jQuery.fn.extend(object);为jQu ...
- js深浅拷贝
作为一枚前段,我们知道对象类型在赋值的过程中其实是复制了地址,从而会导致改变了一方其他也都被改变的情况.通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝来解决这个情况. 浅拷贝 首先可以通过O ...
- JS 深浅拷贝
首先理解概念 浅拷贝: 只复制对象的基本类型, 对象类型, 仍属于原来的引用. 深拷贝: 不紧复制对象的基本类, 同时也复制原对象中的对象.就是说完全是新对象产生的. 首先看浅拷贝 //浅拷贝 var ...
- JS中深浅拷贝 函数封装代码
一.了解 基本数据类型保存在栈内存中,按值访问,引用数据类型保存在堆内存中,按址访问. 二.浅拷贝 浅拷贝只是复制了指向某个对象的指针,而不是复制对象本身,新旧对象其实是同一内存地址的数据,修改其中一 ...
- js 基础数据类型和引用类型 ,深浅拷贝问题,以及内存分配问题
js 深浅拷贝问题 浅拷贝一般指的是基本类型的复制 深拷贝一般指引用类型的拷贝,把引用类型的值也拷贝出来 举例 h5的sessionStorage只能存放字符串,所以要存储json时就要把json使用 ...
- JS--变量及深浅拷贝
JS变量分为基本类型和引用类型 基本类型数据包括Number, String, Boolean, Null, Undefined五种类型: 引用数据类型包括Array, Date, RegExp, F ...
- 【 js 基础 】 深浅拷贝
underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...
随机推荐
- 编辑器——vscode
1.编辑器个人工作配置 // 将设置放入此文件中以覆盖默认设置 { "editor.tabSize": 2, "workbench.iconTheme": &q ...
- ZOJ - 4048 Red Black Tree (LCA+贪心) The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online
题意:一棵树上有m个红色结点,树的边有权值.q次查询,每次给出k个点,每次查询有且只有一次机会将n个点中任意一个点染红,令k个点中距离红色祖先距离最大的那个点的距离最小化.q次查询相互独立. 分析:数 ...
- mycat实战之性能测试
1.安装性能监控工具 1.1 nmon 安装nmon de >#下载地址 http://nmon.sourceforge.net/pmwiki.php?n=Site.Download nmon1 ...
- oracle 11g怎样配置才能连接远程数据库
打开所有程序->找到oracle-oradb11g-home1->Net Configuration Assistant,如图所示 选择本地网络服务名配置,点击下一步 选择添 ...
- IDEA 编译报错: 未结束的字符串文字
最近在搞新项目,同事用的eclipse开发,而我用的是ide,项目初始是由同事创建的,项目编码是UTF-8,而我开发的ide工具默认是GBK编码,导致在编译的时候报错: 未结束的字符串文字 这个问题就 ...
- WeX5基础
最近在研究微信app开发,使用的是WeX5,在这里把一些基础知识点记录下来,忘记了可以翻阅查看. 一:开发后端服务 1.建立数据源:窗口--首选项--studio配置--数据源--增加--数据源类型选 ...
- [原创] css中的绝对定位和相对定位
我对博客的认识是:记录问题,解决问题,分享知识.如果有轮子,我不需要造轮子. 首先,定位无论是相对定位还是绝对定位,必须有一个参考项,而这个参考项,专业术语称之为 包含块,这里的包含块是指在定位时 ...
- Swoole学习(七)Swoole之异步TCP服务器的创建
环境:Centos6.4,PHP环境:PHP7 <?php //创建TCP服务器 /** * $host 是swoole需要监听的ip,如果要监听本地,不对外服务,那么就是127.0.0.1;如 ...
- 从页面到服务器,node实现文件下载
起因: 新来了一个需求,让用户下载一个200m的zip文件,并且校验用户信息,难点:下载的文件是200M的. 现在维护的系统,以前的文件下载,走的是node的静态文件,用的express框架上自带的静 ...
- 在父页面和其iframe之间函数回调 父页面回调iframe里写的函数
// @shaoyang 父页面 window['mengBanLogin']={ mengBanArr : new Array(), mengBanLoginSuccess : function( ...