手写实现深拷贝函数
對象相互賦值的一些關系,分別包括:
- 引入的賦值:指向同一個對象,相互之間會影響;
- 對象的淺拷貝:只是淺層的拷貝,內部引入對象時,依然會相互影響;
- 對象的深拷貝:兩個對象不再有任何關系,不會相互影響;
可以通過JSON.parse來實現深拷貝,但存在以下弊端:
- 這種深拷貝的方式其實對于函數、Symbol等是無法處理的;
- 并且如果存在對象的循環引用,也會報錯的;
一、簡單的深拷貝函數實現
自定義深拷貝的基本功能:
二、對其他數據類型的值進行處理
包括:數組、函數、Symbol、Set、Map
三、對循環引用進行處理
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)總結
- 上一篇: 一、Java Web——JDBC快速入门
- 下一篇: nodejs 创建一个静态资源服务器 +