亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

JS中實現淺拷貝和深拷貝的代碼詳解

2024-05-06 16:51:53
字體:
來源:轉載
供稿:網友

(一)JS中基本類型和引用類型

JavaScript的變量中包含兩種類型的值:基本類型值 和 引用類型值,在內存中的表現形式在于:前者是存儲在棧中的一些簡單的數據段,后者則是保存在堆內存中的一個對象。

基本類型值

在JavaScript中基本數據類型有 String , Number , Undefined , Null , Boolean ,在ES6中,又定義了一種新的基本數據類型 Symbol ,所以一共有6種。

基本類型是按值訪問的,從一個變量復制基本類型的值到另一個變量后,這兩個變量的值是完全獨立的,即使一個變量改變了也不會影響到第二個變量。

var str1 = '撩課';var str2 = str1;str2 = 'itlike';console.log(str2); //'itlike'console.log(str1); //'撩課'

引用類型值

引用類型值是引用類型的實例,它是保存在堆內存中的一個對象,引用類型是一種數據結構,最常用的是Object,Array,Function類型,此外還有Date,RegExp,Error等。

在ES6中提供了Set,Map2種新的數據結構。

(二)JS中如何復制引用類型的

基本類型和引用類型賦值的差異化
舉個例子:在下面代碼中,只修改了obj1中的name屬性,卻同時改變了ob1和obj2中的name屬性。

var obj1 = {'name': '撩課'};var obj2 = obj1;obj2.name = '小撩';console.log(obj1); // {'name': '撩課'}console.log(obj2); // {'name': '撩課'}

當變量復制引用類型值的時候,同樣和基本類型值一樣會將變量的值復制到新變量上,不同的是對于變量的值,它是一個指針,指向存儲在堆內存中的對象。

因為,在JS中,堆內存中的對象無法直接訪問,必須要訪問這個對象在堆內存中的地址,然后再按照這個地址去獲得這個對象中的值。

(三)淺拷貝

在JS中,如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是引用類型,拷貝的就是內存地址;所以如果其中一個對象改變了這個地址,就會影響到另一個對象。

下面是JavaScript提供的淺拷貝方法:

Object.assign

ES6中拷貝對象的方法,接受的第一個參數是拷貝的目標,剩下的參數是拷貝的源對象;

語法:Object.assign(target, ...sources)

var p = {  'name': '張三',};var copyP = {};Object.assign(copyP, p);console.log(copyP);console.log(p);

Object.assign是一個淺拷貝,它只是在根屬性(對象的第一層級)創建了一個新的對象,但是如果屬性的值是對象的話,只會拷貝一份相同的內存地址。

擴展運算符

利用擴展運算符可以在構造字面量對象時,進行克隆或者屬性拷貝。語法如下:

var cloneObj = { ...obj };var obj = {'name': '撩課', 'college': ['H5','JAVA','Python']}var obj2 = {...obj};obj.name='小撩';//{'name': '小撩', 'college': ['H5','JAVA','Python']}console.log(obj);//{'name': '撩課', 'college': ['H5','JAVA','Python']}console.log(obj2); obj.college.push('Go');//{'name': '小撩', 'college': ['H5','JAVA','Python','Go']}console.log(obj); //{'name': '小撩', 'college': ['H5','JAVA','Python','Go']}console.log(obj2);

擴展運算符和Object.assign()存在同樣的問題,對于值是對象的屬性無法完全拷貝成兩個不同對象;

但是如果屬性都是基本類型的值的話,使用擴展運算符更加簡潔。

(四)深拷貝

淺拷貝只在根屬性上在堆內存中創建了一個新的的對象,復制了基本類型的值,但是復雜數據類型也就是對象則是拷貝相同的地址。

而深拷貝則是將一個對象從內存中完整的拷貝一份出來,從堆內存中開辟一個新的區域存放新對象,且修改新對象不會影響原對象。

JSON.stringify

JSON.stringify()是目前開發過程中最常用的深拷貝方式,原理是把一個對象序列化成為一個JSON字符串,將對象的內容轉換成字符串的形式再保存在內存中,再用JSON.parse()反序列化將JSON字符串變成一個新的對象。

舉個例子:

var obj = {  name: '撩課',  age: 18,  friends: ['小花', '小黑'],  goodF: {    name: '小撩',    age: 19,    address: '上海',    pets: [{name: '土豆'}, {name: '馬鈴薯'}]},  bir: new Date()};var newObj = JSON.parse(JSON.stringify(obj));obj.goodF.pets[0].name = '旺財';console.log(newObj);console.log(obj);

使用JSON.stringify實現深拷貝有幾點要注意:

1)拷貝的對象的值中如果有函數,undefined,symbol,經過JSON.stringify()序列化后的JSON字符串中這個鍵值對會消失;

無法拷貝不可枚舉的屬性,無法拷貝對象的原型鏈
3)拷貝Date引用類型會變成字符串

4)拷貝RegExp引用類型會變成空對象

對象中含有NaN、Infinity和-Infinity,則序列化的結果會變成null

遞歸實現深拷貝

具體實現如下:

/** * 輔助函數, 判定是否是對象 * @param obj * @returns {boolean} */function isObj(obj) {  return obj instanceof Object;}/** * 深拷貝fromObj面的所有屬性/值, 到toObj對象里面 * @param fromObj 拷貝對象 * @param toObj  目標對象 */function deepCopyObj2NewObj(fromObj, toObj) {  for (var key in fromObj) {    if(fromObj.hasOwnProperty(key)){      var fromValue = fromObj[key];      // 如果是值類型,那么就直接拷貝賦值      if (!isObj(fromValue)) {        toObj[key] = fromValue;      } else {        // 如果是引用類型,那么就再調用一次這個方法,        // 去內部拷貝這個對象的所有屬性        // fromValue是什么類型, 創建一個該類型的空對象        var tmpObj = new fromValue.constructor;        // console.log(tmpObj);        // debugger;        deepCopyObj2NewObj(fromValue, tmpObj);        toObj[key] = tmpObj;      }    }  }}

(五)總結

1)在日常開發中一般并不需要拷貝很多特殊的引用類型,深拷貝對象使用JSON.stringify是最直接和簡單的方法。

2)實現一個完整的深拷貝是非常復雜的,需要考慮到很多邊界情況。對于特殊的引用類型有拷貝需求的話,建議借助第三方完整的庫。

以上所述是小編給大家介紹的JS中實現淺拷貝和深拷貝的代碼詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩av电影手机在线| 欧美午夜片在线免费观看| 九色精品美女在线| 九色精品免费永久在线| 国产精品www网站| 欧美在线激情视频| 成人亚洲综合色就1024| 欧美午夜女人视频在线| 一级做a爰片久久毛片美女图片| 97avcom| 亚洲欧美综合另类中字| 日韩在线视频免费观看高清中文| 国产精品亚洲精品| 国产精品www色诱视频| 国产精品久久久久久久电影| 欧美日韩高清在线观看| 91av成人在线| 国产精品久久久久久久美男| 国自产精品手机在线观看视频| 日本久久精品视频| 欧美另类老肥妇| 亚洲综合成人婷婷小说| 午夜精品免费视频| 精品国产乱码久久久久久婷婷| 国产ts人妖一区二区三区| 国产97在线|日韩| 综合国产在线视频| 欧美高清在线播放| 成人久久18免费网站图片| 国产日韩欧美视频| 国产精品男人的天堂| 日本欧美一级片| 色偷偷噜噜噜亚洲男人| 最新69国产成人精品视频免费| 亚洲综合av影视| 2019国产精品自在线拍国产不卡| 国产精品视频不卡| 麻豆一区二区在线观看| 午夜伦理精品一区| 久久综合色88| 欧美成人亚洲成人| 色一区av在线| 日本人成精品视频在线| 动漫精品一区二区| 中文字幕av一区中文字幕天堂| 日韩精品在线免费播放| 国产日本欧美一区二区三区在线| 国产精品大片wwwwww| 亚洲香蕉成人av网站在线观看| 日韩欧美中文在线| 91久久久久久久一区二区| 国产精欧美一区二区三区| 亚洲毛片在线看| 欧美伊久线香蕉线新在线| 7777免费精品视频| 亚洲国产精彩中文乱码av在线播放| 日韩av免费网站| 国产精品爽爽爽| 日韩欧美国产免费播放| 久久久国产视频91| 日韩av在线网址| 韩日欧美一区二区| 亚洲成人精品久久| 日韩中文字幕在线| 欧美亚洲激情在线| 日韩电影在线观看中文字幕| 26uuu另类亚洲欧美日本一| 亚洲天堂av在线免费观看| 亚洲第一网站免费视频| 国产美女精彩久久| 亚洲区免费影片| 美女精品视频一区| 久久久久国产精品一区| 日韩av不卡电影| 国产精品日韩在线一区| 欧美性高潮床叫视频| 欧美激情第三页| www日韩欧美| 国产精品美女午夜av| 亚洲人在线观看| 国产精品免费小视频| 国产91精品在线播放| 欧美成人四级hd版| 国产精品影院在线观看| 黑人欧美xxxx| 中文亚洲视频在线| 国产午夜精品一区理论片飘花| 亚洲欧美综合图区| 亚洲国产一区二区三区在线观看| 精品亚洲一区二区三区| 国产精品第一区| 国产精品香蕉国产| 亚洲人免费视频| 97色在线播放视频| 色综合男人天堂| 在线观看免费高清视频97| 成人激情黄色网| 欧美日韩xxx| 国产欧美精品在线播放| 亚洲精品中文字幕有码专区| 国产91在线播放九色快色| 欧美精品九九久久| 欧美国产日产韩国视频| 欧美洲成人男女午夜视频| 国产精品成人免费电影| 色中色综合影院手机版在线观看| 91综合免费在线| 亚洲欧美激情在线视频| 国产精品久久久久久久午夜| 久久国产精品免费视频| 久久99久国产精品黄毛片入口| 国产大片精品免费永久看nba| 成人xxxxx| 久久不射电影网| 中文字幕精品一区久久久久| 国产精品视频白浆免费视频| 精品亚洲一区二区三区四区五区| 少妇高潮 亚洲精品| 亚洲国产精品网站| 成人国产精品久久久久久亚洲| 欧美成人在线免费视频| 中文字幕欧美专区| 国产精品爱久久久久久久| 成人欧美在线视频| 亚洲高清一区二| 亚洲色图日韩av| 精品一区二区三区四区在线| 尤物精品国产第一福利三区| 欧美精品www在线观看| 亚洲欧洲在线观看| 国产欧美精品一区二区三区介绍| 国产亚洲精品久久| 午夜精品久久久久久久99黑人| 国产精品稀缺呦系列在线| 国产亚洲视频中文字幕视频| 欧洲s码亚洲m码精品一区| 国产成人精品一区二区| 国产+成+人+亚洲欧洲| 国产视频精品在线| 国产一区二区三区三区在线观看| 成人激情综合网| 日日摸夜夜添一区| 97久久精品人搡人人玩| 亚洲老头老太hd| 亚洲美女免费精品视频在线观看| 久久精品91久久香蕉加勒比| 黑人巨大精品欧美一区二区一视频| 国产亚洲欧洲黄色| 成人h视频在线| 亚洲va欧美va国产综合剧情| 欧美在线视频在线播放完整版免费观看| 欧美福利视频在线| 久久久之久亚州精品露出| 久久久精品999| 久久久精品免费视频| 最近2019中文免费高清视频观看www99| 久久理论片午夜琪琪电影网| 国产亚洲免费的视频看| 91亚洲精华国产精华| 一区二区三区黄色| 亚洲精品ady| 欧美激情2020午夜免费观看| 欧美日韩中文在线| 欧美日韩黄色大片|