国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

詳解JavaScript對(duì)象的深淺復(fù)制

2019-11-19 16:58:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

從層次上來(lái)看,對(duì)象的復(fù)制可以簡(jiǎn)單地分為淺復(fù)制和深復(fù)制,顧名思義,淺復(fù)制是指只復(fù)制一層對(duì)象的屬性,不會(huì)復(fù)制對(duì)象中的對(duì)象的屬性,對(duì)象的深復(fù)制會(huì)復(fù)制對(duì)象中層層嵌套的對(duì)象的屬性。

在復(fù)制對(duì)象時(shí),除了要復(fù)制對(duì)象的屬性外,還要兼顧到是否保留了對(duì)象的constructor屬性,是否對(duì)每一種數(shù)據(jù)類型(JavaScript常見的數(shù)據(jù)類型有String,Number,Boolean,Data,RegExp,Array,Funtion,Object)都實(shí)現(xiàn)正確的復(fù)制。項(xiàng)目中,我們可以根據(jù)實(shí)際情況,決定需要實(shí)現(xiàn)什么樣程度的復(fù)制。

本文是我在復(fù)制對(duì)象方面的一些心得總結(jié),由淺復(fù)制到深復(fù)制,由只復(fù)制簡(jiǎn)單屬性到復(fù)制Function,RegExp等復(fù)雜屬性,層層遞進(jìn)。如有陳述不當(dāng)之處,煩請(qǐng)指出,不勝感激。

正文

淺復(fù)制

淺復(fù)制只會(huì)依次復(fù)制對(duì)象的每一個(gè)屬性,不會(huì)對(duì)這些屬性進(jìn)行遞歸復(fù)制。下面是一個(gè)簡(jiǎn)單的淺復(fù)制實(shí)現(xiàn)。

//對(duì)象淺復(fù)制        function shadowCopy(obj){ if(typeof obj !== 'object') return obj; for(var prop in obj){  if(obj.hasOwnProperty(prop)){  newObj[prop] = obj[prop];  } } return newObj; }

仔細(xì)觀察,不難發(fā)現(xiàn)上述方法的缺陷:

1.不能正確實(shí)現(xiàn)數(shù)組的淺復(fù)制

2.復(fù)制操作丟失了對(duì)象的constructor屬性

好,我們現(xiàn)在已經(jīng)發(fā)現(xiàn)了問題所在,只需針對(duì)性地解決,一個(gè)還算完美的淺復(fù)制對(duì)象的方法就誕生了!

//對(duì)象淺復(fù)制 function shadowCopy(obj){  if(typeof obj !== 'object') return ;  var newObj;  //保留對(duì)象的constructor屬性  if(obj.constructor === Array){  newObj = [];  } else {  newObj = {};  newObj.constructor = obj.constructor;  }  for(var prop in obj){  if(obj.hasOwnProperty(prop)){   newObj[prop] = obj[prop];  }  }  return newObj; }

瀏覽器中測(cè)試一下:

var arr1 = [0,1,2]; console.log(arr1); console.log(shadowCopy(arr1)); var arr2 = [0,1,2,[3,4,5]], arr2Copy = shadowCopy(arr2); console.log(arr2); console.log(arr2Copy); arr2Copy[3][0] = 6; console.log(arr2[3][0]); //6

Good! 可以正確實(shí)現(xiàn)數(shù)組復(fù)制和并且保留constructor了,但細(xì)心的你一定發(fā)現(xiàn)了,淺復(fù)制后的對(duì)象的 arr2Copy[3] 和 arr2[3] 指向的是一個(gè)對(duì)象,改變其中一個(gè),同時(shí)也會(huì)改變另一個(gè)。我們想要實(shí)現(xiàn)的是 復(fù)制,但這并不是復(fù)制呀!
這是淺復(fù)制的一個(gè)弊端所在,接下讓我們看看深復(fù)制是怎樣解決這個(gè)問題的。

深復(fù)制

深復(fù)制需要層層遞歸,復(fù)制對(duì)象的所有屬性,包括對(duì)象屬性的屬性的屬性....(暈~)
如果只是需要簡(jiǎn)單地復(fù)制對(duì)象的屬性,而不用考慮它的constructor,也不用考慮函數(shù),正則,Data等特殊數(shù)據(jù)類型,那這里有一個(gè)深復(fù)制的小trick,兩行代碼即可:

function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var str = JSON.stringify(obj); return JSON.parse(str);}

大多數(shù)情況下,上面的就可以滿足要求了,但一些時(shí)候,我們需要把函數(shù),正則等特殊數(shù)據(jù)類型也考慮在內(nèi),或者當(dāng)前環(huán)境不支持JSON時(shí),上面的方法也就不適用了。這時(shí),我們可以通過(guò)遞歸來(lái)實(shí)現(xiàn)對(duì)象的深層復(fù)制,如下:

function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var newObj; //保留對(duì)象的constructor屬性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(typeof obj[prop] === 'object'){  if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){  newObj[prop] = obj[prop];  } else {  //遞歸  newObj[prop] = deepCopy(obj[prop]);  } } else {  newObj[prop] = obj[prop]; } } return newObj;}

先用上面的例子測(cè)試:

棒!可以正確實(shí)現(xiàn)多維數(shù)組的復(fù)制,再看是否能實(shí)現(xiàn)函數(shù)和正則的復(fù)制:

function Person(name){ this.name = name; this.age = age; this.search = new RegExp(name); this.say = function(){ console.log(this.name + "今年" + this.age + "歲了"); }}var p1 = new Person("Claiyre",20), p2 = deepCopy(p1);console.log(p1);console.log(p2);p2.age = 22;p1.say();p2.say();

圓滿完成??!

稍加整理,我們就可以得到一個(gè)較為通用的js對(duì)象復(fù)制函數(shù):

function deepCopy(obj){ var newObj = obj.constructor === Array ? []:{}; newObj.constructor = obj.constructor; if(typeof obj !== "object"){  return ; } else if(window.JSON){ //若需要考慮特殊的數(shù)據(jù)類型,如正則,函數(shù)等,需把這個(gè)else if去掉即可 newObj = JSON.parse(JSON.stringify(obj)); } else { for(var prop in obj){  if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){  newObj[prop] = obj[prop];  } else if(typeof obj[prop] === 'object'){  //遞歸  newObj[prop] = deepCopy(obj[prop]);  } else {  newObj[prop] = obj[prop];  } } }  return newObj;}

結(jié)語(yǔ)

面向?qū)ο蟮木幊陶Z(yǔ)言,其核心是對(duì)象,因此深入了解對(duì)象的相關(guān)操作,縱向比較異同,對(duì)學(xué)習(xí)過(guò)程是極有好處的。

以上所述是小編給大家介紹的JavaScript對(duì)象的深淺復(fù)制,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 定襄县| 阳谷县| 察雅县| 子长县| 三都| 吴川市| 乌拉特后旗| 常州市| 当涂县| 方城县| 三门峡市| 昔阳县| 阜新市| 顺昌县| 麻栗坡县| 长顺县| 株洲县| 吉林市| 兰州市| 仙游县| 漠河县| 松潘县| 阿拉善右旗| 禄丰县| 拜城县| 辽中县| 澜沧| 望都县| 平定县| 巴林左旗| 吉水县| 常熟市| 留坝县| 邓州市| 达尔| 赣州市| 冷水江市| 辽源市| 桦南县| 兴隆县| 类乌齐县|