摘要:判斷是深拷貝對象還是數組如果要拷貝的對象的屬性依然是個復合類型,遞歸運用遞歸,當要拷貝的對象或者數組的屬性依然是個對象或者數組時,遞歸調用。遍歷對象聊完了深拷貝和淺拷貝,接下來說一下遍歷。
在js這門語言中,數據存放在堆中,而數據的引用的存放在棧中。
淺拷貝我們說的淺拷貝,指的是,引用地址的拷貝,棧中兩塊不同的引用地址都指向了堆中同樣一塊區域。所以,我們通過一個地址修改了堆中的數據,另外一個引用的地址同樣會改變。
淺拷貝的常見寫法有直接復制賦值,使用Object.assign()也是淺拷貝。
let obj = { "a":1, "b":2, "c":{ "c1":3, "c2":4 } } obj.b = 22 let newObj = obj let newObj2 = Object.assign({},obj) console.log(newObj) // newObj.b為22 console.log(newObj2) // newObj.b也為22深拷貝
和淺拷貝不同的是,深拷貝是多帶帶開辟一段堆內存空間,把之前堆內存中的對象復制,這樣在棧內存的新的引用會指向新的堆內存空間,新老兩塊空間彼此并沒有直接的聯系,這樣的話,我們修改了之前的對象,新拷貝的對象并不會隨之改變。
常見的深拷貝方法有兩種,一種是遞歸,另外一種是JSON序列化。
function deepCopy(obj){ let newObj = obj.constructor === Array ? []: {} //判斷是深拷貝對象還是數組 for(let i in obj){ if(typeof obj[i] === "object") { newObj[i] = deepCopy(obj[i]) // 如果要拷貝的對象的屬性依然是個復合類型,遞歸 } else { newObj[i] = obj[i] } } return newObj } let obj = { "a":1, "b":2, "c":{ "c1":3, "c2":4 } } let arr = [1,2,3,[4,5,6],7] let newObj = deepCopy(obj) let newArr = deepCopy(arr) obj.b = 22 arr[3][1] = 55 console.log(obj.b,newObj.b) // 22 2 console.log(arr[3][1],newArr[3][1]) //55 5
運用遞歸,當要拷貝的對象或者數組的屬性依然是個對象或者數組時,遞歸調用。
除了遞歸的方式,使用JSON序列化可以很方便的解決深拷貝問題。
// 依然使用上面的例子 let newObj = JSON.parse(JSON.stringify(obj))
這種方法很巧妙很簡單,但是,局限性在于不能拷貝繼承的屬性,原型中的屬性。只有在一些簡單的場合才推薦使用。
遍歷對象聊完了深拷貝和淺拷貝,接下來說一下遍歷。因為我們發現,上面深拷貝的時候執行遞歸的時候,采用的是for ...in的遍歷方式。
除了for...in,在js中的遍歷方式還有很多,比如Object.keys(),for...of等等,那么這些遍歷方式有什么不同呢。
Object.keys()這個方法用于遍歷,能夠遍歷出來的東西是對象中所有的可枚舉的屬性,但是不包括繼承過來了。
for...infor...in一般用于遍歷對象,能夠返回對象包括繼承過來的可枚舉屬性。
Object.getOwnPropertyNames(obj)返回對象所有的屬性,也包括不可枚舉的屬性。但是不包括繼承過來的。
這個函數會返回一個數組。
這三個遍歷對象的方法,都不會返回對象中的symbol屬性。
遍歷數組和遍歷對象不同,遍歷數組也有一些方法。
for...infor...in除了可以遍歷對象,也可以遍歷數組,所以上面的例子我們可以用for...in分別遍歷對象和數組。
forEach()這是ES5新提供的一個方法,接收一個函數作為參數,回調函數。
for...ofES6提供的遍歷器,除了可以遍歷數組,還支持類數組對象,甚至是字符串,其實就是繼承了Iterator接口的數據結構都可以用for...of來遍歷。
for...of循環可以使用的范圍包括數組、Set 和 Map 結構、某些類似數組的對象(比如arguments對象、DOM NodeList 對象)、后文的 Generator 對象,以及字符串。
我認為,遍歷數組,使用for...of效果最佳。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93053.html
摘要:淺拷貝深拷貝淺拷貝的問題如果父對象的屬性等于數組或另一個對象,那么實際上,子對象獲得的只是一個內存地址,而不是真正拷貝,因此存在父對象被篡改的可能。 淺拷貝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷貝: function deepCopy(p...
摘要:前言里面淺拷貝和深拷貝是非常關鍵的知識點,今天就來通過本文清楚的了解深淺拷貝以及該如何實現這兩種拷貝方式。對象的拷貝又分為淺拷貝和深拷貝。印證了上述所說的對于所有的基本類型,簡單的賦值已經是實現了深拷貝。 前言 JavaScript里面淺拷貝和深拷貝是非常關鍵的知識點,今天就來通過本文清楚的了解深淺拷貝以及該如何實現這兩種拷貝方式。 深淺拷貝的區別 拷貝:其實就是一個對象復制給另外...
閱讀 1972·2021-09-09 09:33
閱讀 1113·2019-08-30 15:43
閱讀 2662·2019-08-30 13:45
閱讀 3304·2019-08-29 11:00
閱讀 854·2019-08-26 14:01
閱讀 3568·2019-08-26 13:24
閱讀 477·2019-08-26 11:56
閱讀 2686·2019-08-26 10:27