JavaScript深浅拷贝
深浅拷贝
基本类型和引用类型
- ECMAScript 中的变量类型分为两类:
- 基本类型:undefined,null,布尔值(Boolean),字符串(String),数值(Number)
- 引用类型: 统称为Object类型,细分的话,有:Object类型,Array类型,Date类型,Function类型等。
- 不同类型的存储方式:
基本数据类型 保存在 栈内存,形式如下:栈内存中分别存储着变量的标识符以及变量的值。
引用类型 保存在 堆内存 中, 栈内存存储的是变量的标识符以及对象在堆内存中的存储地址,当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从对应的堆内存中取得所需的数据。
对于仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响,为 浅拷贝。
而如果是在堆中重新分配内存,拥有不同的地址,但是值是一样的,复制后的对象与原来的对象是完全隔离,互不影响,为 深拷贝。
深浅拷贝 的主要区别就是:复制的是引用(地址)还是复制的是实例。
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);
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);
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);
但是该方法也是有局限性的:
- 会忽略 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];
}
}
}
}
JavaScript深浅拷贝的更多相关文章
- JavaScript深浅拷贝区别
分享一篇自己关注的微信订阅号(前端大全)文章:JavaScript浅拷贝与深拷贝 作者:浪里行舟 https://github.com/ljianshu/Blog/issues/5 这里很详细的讲解了 ...
- JavaScript 深浅拷贝
JavaScript有五种基本数据类型(Undefined, null, Boolean, String, Number),还有一种复杂的数据类型,就是对象. Undefined 其实是已声明但没有赋 ...
- 谈谈JavaScript深浅拷贝
浅拷贝 function shallowCopy(source){ var newObj = {}; for(var attr in source){ newObj[attr] = source[at ...
- javascript简单实现深浅拷贝
深浅拷贝知识在我们的日常开发中还算是用的比较多,但是之前的状态一直都是只曾听闻,未曾使用(其实用了只是自己没有意识到),所以今天来跟大家聊一聊js的深浅拷贝: 首先我们来了解一下javascript的 ...
- JavaScript数据存储和深浅拷贝实际运用
JavaScript分两种数据类型.1.简单数据类型有:number, string, boolean, undefined和null当声明一个简单数据类型的变量时,在内存中会把数据存在栈里.2.复杂 ...
- JavaScript中的事件委托机制跟深浅拷贝
今天聊下JavaScript中的事件委托跟深浅拷贝 事件委托 首先呢,介绍一下事件绑定 //方法一:通过onclick <button onclick="clickEvent()&qu ...
- javascript实现深浅拷贝
深浅拷贝通常是对于引用数据类型进行的(数据类型为:对象(Object).数组(Array).函数(Function)) 浅拷贝: let obj = {id: 1, name: 2}; let new ...
- Javascript 中的深浅拷贝
工作中经常会遇到需要复制 JS 数据的时候,遇到 bug 时实在令人头疼:面试中也经常会被问到如何实现一个数据的深浅拷贝,但是你对其中的原理清晰吗?一起来看一下吧! 为什么会有深浅拷贝 想要更加透彻的 ...
- JavaScript中的深浅拷贝
深浅拷贝 在JS中,数据类型分为两类: 简单数据类型:Number.Boolean.String.undefined 引用数据类型:Array.Object.Function 简单数据类型通常 ...
随机推荐
- Change Jenkins time zone
修改Jenkins时区 Debian: vim /etc/defalut/jenkins JAVA_ARGS="-Dorg.apache.commons.jelly.tags.fmt.tim ...
- DBCC--EXTENTINFO/IND/PAGE--显示数据页信息
DBCC EXTENTINFO得到对象分配的区DBCC EXTENTINFO(<dbname|dbid>,<tabelname|tableid>[,{indexname|ind ...
- Checkpoint--查看各DB上的脏页
可以使用sys.dm_os_buffer_descriptors来看数据页在buffer pool中的状态,其中is_modified来标示数据页是否为脏页 --------------------- ...
- ajax方式上传图片到Django后台
参考价值最大 https://blog.csdn.net/huangql517/article/details/81259671 https://www.cnblogs.com/chenjianhon ...
- leetcode 缺失数字
给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数. 示例 1: 输入: [3,0,1] 输出: 2 示例 2: 输入: [9,6,4,2 ...
- .NET Core中使用Dapper操作Oracle存储过程最佳实践
为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDir ...
- 程序媛计划——python初级课时3~5
产生1-10中的随机数: for 循环:所有可遍历对象都能用于for循环,如一个字符串. len(list),list中的元素类型可以各不相同:可以直接用下标对list元素赋值来更新列表 对字符串可以 ...
- 在html页面添加一个隐藏域,并渲染一个需要保存的数值,在js中需要再获取,而不影响页面结构
<div style="display:none">可以将需要保存的数值放在文本内容中,也可以放在标签的属性当中, 如果放在文本内容中,注意换行后 \n 的存在< ...
- Good Bye 2017(送命场)
9815人数场,9500+围观神仙打架...断断续续打Codeforces也快有一年啦,第一次打Good Bye场,满怀前排膜tourist的心愿参加了这场送命场,虽然没看到tourist.不过还是得 ...
- [bug] VUE 的 template 中使用 ES6 语法导致页面空白
如果你在 template 中,使用了 es6 及以上的语法,那么,在部分ios.安卓.微信浏览器中,打开页面后显示一片空白内容.如下: <ul id="example-1" ...