js对象浅拷贝与深拷贝
一、簡介
? ?淺拷貝是拷貝一層,如果數據是基本數據類型,會拷貝其本身,如果除了基本數據類型之外還有一層對象,那么只能拷貝其引用,對象的改變會反應到拷貝對象上。
? ?深拷貝是拷貝多層,每一層的數據都會拷貝出來,對象的改變不會影響拷貝對象。
二、實現
? ?1、實現淺拷貝
? ? ? 1)數組自帶的淺拷貝方法:slice()、concat、Array.from()、... 操作符
通過上圖我們可以看到,arr1不通過淺拷貝直接賦值, 此時arr1復制的是arr的引用,arr值改變arr1也會改變,而淺拷貝則不會。
? ? ? 2)對象自帶的淺拷貝方法:... 操作符、Object.assign()
通過上圖我們可以看到,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对象浅拷贝与深拷贝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 武汉理工大学计算机学院调剂,武汉理工大学
- 下一篇: tcpdump 命令使用教程