日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手写实现深拷贝函数

發布時間:2024/7/5 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手写实现深拷贝函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對象相互賦值的一些關系,分別包括:

  • 引入的賦值:指向同一個對象,相互之間會影響;
  • 對象的淺拷貝:只是淺層的拷貝,內部引入對象時,依然會相互影響;
  • 對象的深拷貝:兩個對象不再有任何關系,不會相互影響;

可以通過JSON.parse來實現深拷貝,但存在以下弊端:

  • 這種深拷貝的方式其實對于函數、Symbol等是無法處理的;
  • 并且如果存在對象的循環引用,也會報錯的;

一、簡單的深拷貝函數實現

自定義深拷貝的基本功能:

二、對其他數據類型的值進行處理

包括:數組、函數、Symbol、Set、Map

function isObject(value) {const valueType = typeof valuereturn (value !== null) && (valueType === "object" || valueType === "function") }function deepClone(originValue) {// 判斷是否是一個Set類型if (originValue instanceof Set) {return new Set([...originValue])}// 判斷是否是一個Map類型if (originValue instanceof Map) {return new Map([...originValue])}// 判斷如果是Symbol的value, 那么創建一個新的Symbolif (typeof originValue === "symbol") {return Symbol(originValue.description)}// 判斷如果是函數類型, 那么直接使用同一個函數if (typeof originValue === "function") {return originValue}// 判斷傳入的originValue是否是一個對象類型if (!isObject(originValue)) {return originValue}// 判斷傳入的對象是數組, 還是對象const newObject = Array.isArray(originValue) ? []: {}for (const key in originValue) {newObject[key] = deepClone(originValue[key])}// 上面的for循環是遍歷不到key為Symbol的// 需要對key為Symbol的清空進行特殊處理const symbolKeys = Object.getOwnPropertySymbols(originValue)for (const sKey of symbolKeys) {// const newSKey = Symbol(sKey.description)newObject[sKey] = deepClone(originValue[sKey])}return newObject }// 測試代碼 let s1 = Symbol("aaa") let s2 = Symbol("bbb")const obj = {name: "why",age: 18,friend: {name: "james",address: {city: "廣州"}},// 數組類型hobbies: ["abc", "cba", "nba"],// 函數類型foo: function(m, n) {console.log("foo function")console.log("100代碼邏輯")return 123},// Symbol作為key和value[s1]: "abc",s2: s2,// Set/Mapset: new Set(["aaa", "bbb", "ccc"]),map: new Map([["aaa", "abc"], ["bbb", "cba"]]) }const newObj = deepClone(obj) console.log(newObj === obj) // falseobj.friend.name = "kobe" obj.friend.address.city = "成都" console.log(newObj) console.log(newObj.s2 === obj.s2) // false

三、對循環引用進行處理

function isObject(value) {const valueType = typeof valuereturn (value !== null) && (valueType === "object" || valueType === "function") }function deepClone(originValue, map = new WeakMap()) {// 判斷是否是一個Set類型if (originValue instanceof Set) {return new Set([...originValue])}// 判斷是否是一個Map類型if (originValue instanceof Map) {return new Map([...originValue])}// 判斷如果是Symbol的value, 那么創建一個新的Symbolif (typeof originValue === "symbol") {return Symbol(originValue.description)}// 判斷如果是函數類型, 那么直接使用同一個函數if (typeof originValue === "function") {return originValue}// 判斷傳入的originValue是否是一個對象類型if (!isObject(originValue)) {return originValue}// 判斷當前傳進來的對象是否已經在map中存在,如果是的話,// 直接返回key為這個對象的value,也就是我們所創建出來的newObject對象if (map.has(originValue)) {return map.get(originValue)}// 判斷傳入的對象是數組, 還是對象const newObject = Array.isArray(originValue) ? []: {}// 在第一次創建好newObject對象后,將其存去map中,key為需要進行深拷貝的對象,值為新創建好newObject對象map.set(originValue, newObject)for (const key in originValue) {newObject[key] = deepClone(originValue[key], map) // 把map作為函數的第二個參數傳入}// 對Symbol的key進行特殊的處理const symbolKeys = Object.getOwnPropertySymbols(originValue)for (const sKey of symbolKeys) {// const newSKey = Symbol(sKey.description)newObject[sKey] = deepClone(originValue[sKey], map) // 把map作為函數的第二個參數傳入}return newObject }// deepClone({name: "why"})// 測試代碼 let s1 = Symbol("aaa") let s2 = Symbol("bbb")const obj = {name: "why",age: 18,friend: {name: "james",address: {city: "廣州"}},// 數組類型hobbies: ["abc", "cba", "nba"],// 函數類型foo: function(m, n) {console.log("foo function")console.log("100代碼邏輯")return 123},// Symbol作為key和value[s1]: "abc",s2: s2,// Set/Mapset: new Set(["aaa", "bbb", "ccc"]),map: new Map([["aaa", "abc"], ["bbb", "cba"]]) }obj.info = objconst newObj = deepClone(obj) console.log(newObj === obj)obj.friend.name = "kobe" obj.friend.address.city = "成都" console.log(newObj) console.log(newObj.s2 === obj.s2)console.log(newObj.info.info.info)

總結

以上是生活随笔為你收集整理的手写实现深拷贝函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。