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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

js对象浅拷贝与深拷贝

發布時間:2023/12/31 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js对象浅拷贝与深拷贝 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、簡介

? ?淺拷貝是拷貝一層,如果數據是基本數據類型,會拷貝其本身,如果除了基本數據類型之外還有一層對象,那么只能拷貝其引用,對象的改變會反應到拷貝對象上。
? ?深拷貝是拷貝多層,每一層的數據都會拷貝出來,對象的改變不會影響拷貝對象。

二、實現

? ?1、實現淺拷貝
? ? ?
1)數組自帶的淺拷貝方法:slice()、concat、Array.from()、... 操作符

let arr = [1, 2, 3]; let arr1 = arr; //以下4種方式實現數組淺拷貝 let arr2 = arr.slice(); let arr2 = [...arr] let arr2 = [].concat(arr); let arr2 = Array.from(arr) arr[0] = 4; console.log(arr, arr1, arr2)


通過上圖我們可以看到,arr1不通過淺拷貝直接賦值, 此時arr1復制的是arr的引用,arr值改變arr1也會改變,而淺拷貝則不會。


? ? ? 2)對象自帶的淺拷貝方法:... 操作符、Object.assign()

let obj = {a: 1,b: 2}let obj1 = obj;//以下是對象兩種自帶的淺拷貝方法let obj2 = Object.assign({}, obj)let { ...obj2 } = obj;obj.a = 3;console.log(obj, obj1, obj2)

通過上圖我們可以看到,obj1不通過淺拷貝直接賦值, 此時obj1復制的是obj的引用,obj值改變obj1也會改變,而淺拷貝則不會。

2.實現深拷貝

?1)通過JSON.parse(JSON.stringify(obj))
? ??這個方法簡單,平常項目也常拿來使用。缺點:會忽略undefined、任意的函數、正則、symbol 值等;?Date類型會轉為字符串

?2)簡單實現深拷貝方法

function deepClone(obj){let objClone = Array.isArray(obj)?[]:{};if(obj && typeof obj==="object"){for(key in obj){if(obj.hasOwnProperty(key)){//判斷ojb子元素是否為對象,如果是,遞歸復制if(obj[key]&&typeof obj[key] ==="object"){objClone[key] = deepClone(obj[key]);}else{//如果不是,簡單復制objClone[key] = obj[key];}}}}return objClone; }

目前只考慮簡單的對象和數組兩種情況,沒有考慮日期,正則等等其他情況。主要是,當對象的子項還是對象類型時,遞歸調用。

考慮更多情況深拷貝實現

function isType(obj, type) {if (typeof obj !== 'object') return false;return Object.prototype.toString.call(obj).replace('[object ', '').replace(']', '') === type}const getRegExp = re => {var flags = '';if (re.global) flags += 'g';if (re.ignoreCase) flags += 'i';if (re.multiline) flags += 'm';return flags;};const clone = parent => {// 維護兩個儲存循環引用的數組const parents = [];const children = [];const _clone = parent => {if (parent === null) return null;if (typeof parent !== 'object') return parent;let child, proto;if (isType(parent, 'Array')) {// 對數組做特殊處理child = [];} else if (isType(parent, 'RegExp')) {// 對正則對象做特殊處理child = new RegExp(parent.source, getRegExp(parent));if (parent.lastIndex) child.lastIndex = parent.lastIndex;} else if (isType(parent, 'Date')) {// 對Date對象做特殊處理child = new Date(parent.getTime());} else {// 處理對象原型proto = Object.getPrototypeOf(parent);// 利用Object.create切斷原型鏈child = Object.create(proto);}// 處理循環引用const index = parents.indexOf(parent);if (index != -1) {// 如果父數組存在本對象,說明之前已經被引用過,直接返回此對象return children[index];}parents.push(parent);children.push(child);for (let i in parent) {// 遞歸child[i] = _clone(parent[i]);}return child;};return _clone(parent);};function person(pname) {this.name = pname;}const Messi = new person('Messi');function say() {console.log('hi');}const oldObj = {a: say,c: new RegExp('ab+c', 'i'),d: Messi,};oldObj.b = oldObj;const newObj = clone(oldObj);console.log(newObj)

3.有些第三方庫也封裝好了深拷貝的方法
如 loadash的cloneDeep方法

深拷貝的也可參考這篇文章

總結

以上是生活随笔為你收集整理的js对象浅拷贝与深拷贝的全部內容,希望文章能夠幫你解決所遇到的問題。

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