基本数据类型 保存在 栈内存,形式以下:栈内存中分别存储着变量的标识符以及变量的值。jquery
引用类型 保存在 堆内存 中, 栈内存存储的是变量的标识符以及对象在堆内存中的存储地址,当须要访问引用类型(如对象,数组等)的值时,首先从栈中得到该对象的地址指针,而后再从对应的堆内存中取得所需的数据。json
对于仅仅是复制了引用(地址),换句话说,复制了以后,原来的变量和新的变量指向同一个东西,彼此之间的操做会互相影响,为 浅拷贝。数组
而若是是在堆中从新分配内存,拥有不一样的地址,可是值是同样的,复制后的对象与原来的对象是彻底隔离,互不影响,为 深拷贝。函数
深浅拷贝 的主要区别就是:复制的是引用(地址)仍是复制的是实例。性能
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);
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 复制方法 则 取决于 你的 第一个参数, 也就是是否进行递归复制。prototype
JOSN 对象中的 stringify 能够把一个 js 对象序列化为一个 JSON 字符串,parse 能够把 JSON 字符串反序列化为一个 js 对象,这两个方法实现的是深拷贝。3d
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);
可是该方法也是有局限性的:指针
这个函数能够解决大部分问
题,而且该函数是内置函数中处理深拷贝性能最快的。若是你的数据中含有以上三种状况下,可使用 lodash 的深拷贝函数。code
固然,也能够利用递归本身封装深度克隆函数,对象
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]; } } } }