摘要:淺拷貝實現方式賦值。但是進行的是淺拷貝,拷貝的是對象的屬性的引用,而不是對象本身。沒復制遞歸拷貝避免相互引用對象導致死循環,如的情況使用方法直接使用,可以達到深拷貝的效果。
js有五種基本數據類型,string,number,boolean,null,undefind。這五種類型的賦值,就是值傳遞。特殊類型對象的賦值是將對象地址的引用賦值。這時候修改對象中的屬性或者值,會導致所有引用這個對象的值改變。如果想要真的復制一個新的對象,而不是復制對象的引用,就要用到對象的深拷貝。
淺拷貝實現方式 1.‘=’賦值。不多說,最基礎的賦值方式,只是將對象的引用賦值。
2.Object.assign()Object.assign是ES6的新函數。Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標對象,然后返回目標對象。但是 Object.assign() 進行的是淺拷貝,拷貝的是對象的屬性的引用,而不是對象本身。
Object.assign(target, ...sources)
參數:
target:目標對象。
sources:任意多個源對象。
返回值:目標對象會被返回。
var obj = { a: {a: "hello", b: 21} }; var initalObj = Object.assign({}, obj); initalObj.a.a = "changed"; console.log(obj.a.a); // "changed"
需要注意的是:
Object.assign()可以處理一層的深度拷貝,如下:
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = Object.assign({}, obj1); obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- 沒被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }深拷貝 1.手動復制
var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }; obj2.b = 100; console.log(obj1); // { a: 10, b: 20, c: 30 } <-- 沒被改到 console.log(obj2); // { a: 10, b: 100, c: 30 }2.JSON做字符串轉換
用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象。
var obj1 = { body: { a: 10 } }; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.body.a = 20; console.log(obj1); // { body: { a: 10 } } <-- 沒被改到 console.log(obj2); // { body: { a: 20 } } console.log(obj1 === obj2); // false console.log(obj1.body === obj2.body); // false
這樣做是真正的Deep Copy,這種方法簡單易用。
但是這種方法也有不少壞處,譬如它會拋棄對象的constructor。也就是深拷貝之后,不管這個對象原來的構造函數是什么,在深拷貝之后都會變成Object。
這種方法能正確處理的對象只有 Number, String, Boolean, Array, 扁平對象,即那些能夠被 json 直接表示的數據結構。RegExp對象是無法通過這種方式深拷貝。
也就是說,只有可以轉成JSON格式的對象才可以這樣用,像function沒辦法轉成JSON。
var obj1 = { fun: function(){ console.log(123) } }; var obj2 = JSON.parse(JSON.stringify(obj1)); console.log(typeof obj1.fun); // "function" console.log(typeof obj2.fun); // "undefined" <-- 沒復制3.遞歸拷貝
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用對象導致死循環,如initalObj.a = initalObj的情況 if(prop === obj) { continue; } if (typeof prop === "object") { obj[i] = (prop.constructor === Array) ? [] : {}; arguments.callee(prop, obj[i]); } else { obj[i] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str); console.log(str.a);4.使用Object.create()方法
直接使用var newObj = Object.create(oldObj),可以達到深拷貝的效果。
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用對象導致死循環,如initalObj.a = initalObj的情況 if(prop === obj) { continue; } if (typeof prop === "object") { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj; }5.jquery
jquery 有提供一個$.extend可以用來做 Deep Copy。
var $ = require("jquery"); var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] }; var obj2 = $.extend(true, {}, obj1); console.log(obj1.b.f === obj2.b.f); // false6.第三方函數
還有一些其它的第三方函數庫有深拷貝function,如lodash。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97883.html
摘要:原文地址淺拷貝和深拷貝只針對像這樣的復雜對象的簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。淺拷貝通過來實現淺拷貝。 原文地址:http://www.silenceboy.com/201... 淺拷貝和深拷貝只針對像Object, Array這樣的復雜對象的.簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。 淺拷貝 通過 Object.ass...
摘要:所以,深拷貝是對對象以及對象的所有子對象進行拷貝實現方式就是遞歸調用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 為什么會有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實現淺拷貝與深拷貝好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現紕漏、錯誤之處,還請看到的小伙伴多多指教,先行謝過 以下↓ 數據類型在開始了解 淺拷貝 與 深拷貝 之前,讓我們先...
摘要:所以,深拷貝是對對象以及對象的所有子對象進行拷貝實現方式就是遞歸調用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 上一篇 JavaScript中的繼承 前言 文章開始之前,讓我們先思考一下這幾個問題: 為什么會有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實現淺拷貝與深拷貝 好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現紕漏、錯誤之處...
摘要:什么是深拷貝,什么是淺拷貝中的淺拷貝與深拷貝是針對復雜數據類型引用類型的復制問題。 什么是深拷貝,什么是淺拷貝 JS中的淺拷貝與深拷貝是針對復雜數據類型(引用類型)的復制問題。 淺拷貝:淺拷貝是拷貝引用(拷貝地址),拷貝后兩個變量指向的是同一塊內存空間 深拷貝:會在內存中開辟一塊新的內存空間,它不僅將原對象的各個屬性逐個復制過去,而且將原對象各個屬性所包含的內容也依次采用深復制的方法...
摘要:淺拷貝深拷貝淺拷貝的問題如果父對象的屬性等于數組或另一個對象,那么實際上,子對象獲得的只是一個內存地址,而不是真正拷貝,因此存在父對象被篡改的可能。 淺拷貝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷貝: function deepCopy(p...
閱讀 1393·2021-11-22 15:11
閱讀 2838·2019-08-30 14:16
閱讀 2755·2019-08-29 15:21
閱讀 2914·2019-08-29 15:11
閱讀 2450·2019-08-29 13:19
閱讀 2985·2019-08-29 12:25
閱讀 417·2019-08-29 12:21
閱讀 2829·2019-08-29 11:03