欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解JavaScript對象的深淺復制

 更新時間:2017年03月30日 09:25:46   作者:Claiyre  
從層次上來看,對象的復制可以簡單地分為淺復制和深復制,顧名思義,淺復制是指只復制一層對象的屬性,不會復制對象中的對象的屬性,對象的深復制會復制對象中層層嵌套的對象的屬性。本文是我在復制對象方面的一些心得總結,由淺復制到深復制,感興趣的朋友一起學習吧

前言

從層次上來看,對象的復制可以簡單地分為淺復制和深復制,顧名思義,淺復制是指只復制一層對象的屬性,不會復制對象中的對象的屬性,對象的深復制會復制對象中層層嵌套的對象的屬性。

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

本文是我在復制對象方面的一些心得總結,由淺復制到深復制,由只復制簡單屬性到復制Function,RegExp等復雜屬性,層層遞進。如有陳述不當之處,煩請指出,不勝感激。

正文

淺復制

淺復制只會依次復制對象的每一個屬性,不會對這些屬性進行遞歸復制。下面是一個簡單的淺復制實現(xiàn)。

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

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

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

2.復制操作丟失了對象的constructor屬性

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

//對象淺復制
 function shadowCopy(obj){
  if(typeof obj !== 'object') return ;
  var newObj;
  //保留對象的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;
 }

瀏覽器中測試一下:

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

深復制

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

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

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

function deepCopy(obj){
 if(typeof obj !== "object"){ return ;}
 var newObj;
 //保留對象的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;
}

先用上面的例子測試:

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

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();

圓滿完成??!

稍加整理,我們就可以得到一個較為通用的js對象復制函數(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ù)等,需把這個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;
}

結語

面向對象的編程語言,其核心是對象,因此深入了解對象的相關操作,縱向比較異同,對學習過程是極有好處的。

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

相關文章

  • Javascript類型轉換詳解

    Javascript類型轉換詳解

    這篇文章主要為大家介紹了Javascript類型轉換,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • js實現(xiàn)圖片緩慢放大縮小效果

    js實現(xiàn)圖片緩慢放大縮小效果

    這篇文章主要為大家詳細介紹了js實現(xiàn)圖片緩慢放大縮小效果的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • js直接編輯當前cookie的腳本

    js直接編輯當前cookie的腳本

    非常有創(chuàng)意的一個腳本,直接利用window.prompt彈出修改對話框,不用到cookies目錄去找cookies文件
    2008-09-09
  • js屏蔽鼠標鍵盤(右鍵/Ctrl+N/Shift+F10/F11/F5刷新/退格鍵)

    js屏蔽鼠標鍵盤(右鍵/Ctrl+N/Shift+F10/F11/F5刷新/退格鍵)

    屏蔽鼠標右鍵、Ctrl+N、Shift+F10、F11、F5刷新、退格鍵/Alt+ 方向鍵 →等等,太多了就不一一寫來了感興趣的朋友可以了解下啊,希望本文對你有所幫助
    2013-01-01
  • JavaScript讀寫二進制數(shù)據(jù)的方法詳解

    JavaScript讀寫二進制數(shù)據(jù)的方法詳解

    avascript里有兩個內置對象,一個是ArrayBuffer;一個是DataView,讀寫二進制數(shù)據(jù)都需要使用這兩個對象。這篇文章主要給大家介紹了關于JavaScript讀寫二進制數(shù)據(jù)的方法,需要的朋友可以參考下
    2018-09-09
  • JS實現(xiàn)的點擊表頭排序功能示例

    JS實現(xiàn)的點擊表頭排序功能示例

    這篇文章主要介紹了JS實現(xiàn)的點擊表頭排序功能,可實現(xiàn)針對表格中的字母、數(shù)字、日期等格式進行排序的功能,涉及javascript針對頁面table元素的獲取及字符串、數(shù)字等排序操作相關技巧,需要的朋友可以參考下
    2017-03-03
  • javascript中的閉包概念與用法實踐分析

    javascript中的閉包概念與用法實踐分析

    這篇文章主要介紹了javascript中的閉包概念與用法,結合具體實例形式分析了javascript閉包的概念、原理、使用方法及相關操作注意事項,需要的朋友可以參考下
    2019-07-07
  • layui的table中顯示圖片方法

    layui的table中顯示圖片方法

    今天小編就為大家分享一篇layui的table中顯示圖片方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • 如何在微信小程序中使用骨架屏的步驟

    如何在微信小程序中使用骨架屏的步驟

    這篇文章主要介紹了如何在微信小程序中使用骨架屏的步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • js隨機生成字母數(shù)字組合的字符串 隨機動畫數(shù)字

    js隨機生成字母數(shù)字組合的字符串 隨機動畫數(shù)字

    本篇文章給大家分享的js隨機生成字母數(shù)字組合的字符串,js隨機生成動畫數(shù)字,包括常用的產(chǎn)生隨機數(shù)的用法,需要的朋友可以參考下
    2015-09-09

最新評論