基本數據類型 保存在 棧內存,形式以下:棧內存中分別存儲着變量的標識符以及變量的值。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]; } } } }