最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中的兩種數據類型及實現引用類型的深拷貝的方法

 更新時間:2018年08月12日 09:25:18   作者:難涼熱血,前端菜雞!  
大家都知道在JS中數據類型按照訪問方式和存儲方式的不同可分為基本類型和引用類型。這篇文章主要介紹了JS中的兩種數據類型以及實現引用類型的深拷貝 ,需要的朋友可以參考下

一.前言

我們知道,在JS中數據類型按照訪問方式和存儲方式的不同可分為基本類型和引用類型。

基本類型

基本類型有String、Boolean、Number,Undefined、Null,這些基本類型都是按值傳遞的,也稱為值類型。

引用類型

引用類型有對象、數組、函數,它們都是按引用訪問的。

二.存儲方式區(qū)別

基本類型和引用類型由于兩者在內存中存儲的方式不同,造成兩者訪問的方式也不同。其中,基本類型存儲在內存的棧中,是按值訪問;引用類型存儲在內存的堆中,是按引用訪問??扇缦聢D所示:

當有

 var n1 = 10;
 var n2 = 10;
 var arr1 = [1,2,3,4]
 var arr2 = [1,2,3,4]

其在內存中存儲方式如圖:

值類型是在棧中直接保存的變量的實際值,而引用類型在棧中僅僅保存的是變量指向堆中的地址,從上圖中可以看出,值類型的變量n1和n2都是10,但是在棧中卻為這兩個變量分別開辟了兩塊空間來存儲,而引用類型的變量arr1和arr2也相同,但是在堆中僅僅開辟了一塊內存來存儲,而在棧中存儲的是這兩個變量指向堆中的地址,這兩個變量都指向堆中的同一片地址。

三.拷貝區(qū)別

正是由于兩者在存儲方式上的不同,造成了兩者在拷貝時的差異。首先,先看兩段代碼:

 var n1 = 10;
 //將n1拷貝給n2
 var n2 = n1;
 n1 = 12;
 console.log(n1);
 console.log(n2);

先定義變量n1=10,然后將n1拷貝給n2,再接著改變n1的值為12,分別打印n1和n2的值,打印結果為:

從結果中我們可以看到,n1變?yōu)?2了,但是n2不受影響,依舊是10。

再看另外一段代碼:

 var arr1 = [1,2,3,4]
 //將arr1拷貝給arr2
 var arr2 = arr1;
 //向arr1中尾部添加一個元素5
 arr1.push(5); 
 console.log(arr1);
 console.log(arr2);

先定義數組arr1,然后將arr1拷貝給arr2,再接著向arr1中尾部追加一個元素,分別打印arr1和arr2的值,打印結果為:

從結果中我們可以看到:我們先將arr1拷貝給了arr2,但是當我們改變arr1時,arr2也跟著一起改變了。這印證了前文所說的,arr1和arr2實際上是指向了內存中的同一片地址,當arr1發(fā)生變化時,實際上是將指向的這片內存地址中的數據變化了,而arr2也指向的是這片地址,所以arr2也會跟著變化。

上面代碼中的arr2=arr1,就是我們俗稱的淺拷貝,淺拷貝僅僅拷貝的是變量名,其在內存的存儲沒有被拷貝,指向的還是同一片內存地址,這就是造成了一個變化另外一個也跟著變化,這在日常開發(fā)中不是我們想要的。

那如何實現真正的拷貝呢?

四.實現深拷貝

真正的拷貝,就是拷貝過后,arr1和arr2指向的不再是同一片內存地址,而是分別指向各自的地址,這樣發(fā)生變化的時候就不會出現同時變化,這就是深拷貝。

下面我們封裝一個深拷貝函數,來實現引用類型的深拷貝:

 //參數p為原對象
 //參數c為原對象的類型,若原對象為數組,則傳入c為[],若原對象是對象傳入c為{},也可不傳默認為{}
 function deepCopy(p,c){
 var c = c || {};
 for(var i in p){
   if(typeof p[i] === "object"){
     c[i] = (p[i].constructor === Array)?[]:{};
     deepCopy(p[i],c[i])
     }else{
     c[i] = p[i]
    }
   }
   return c;
 }

五.測試

 //參數p為原對象
 //參數c為原對象的類型,若原對象為數組,則傳入c為[],若原對象是對象傳入c為{},也可不傳默認為{}
 function deepCopy(p,c){
 var c = c || {};
 for(var i in p){
   if(typeof p[i] === "object"){
      c[i] = (p[i].constructor === Array)?[]:{};
      deepCopy(p[i],c[i])
     }else{
       c[i] = p[i]
     }
   }
   return c;
 }
 //定義數組arr1
 var arr1 = [1,2,3,4]
 //將arr1拷貝給arr2
 var arr2 = deepCopy(arr1,[]);
 //向arr1中尾部添加一個元素5
 arr1.push(5);
 console.log('arr1:',arr1);
 console.log('arr2:',arr2);

測試結果:

結果中可以看到,arr1變化沒有引起arr2的變化,實現了真正的拷貝。

總結

以上所述是小編給大家介紹的JS中的兩種數據類型及實現引用類型的深拷貝的方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

相關文章

  • 詳解JavaScript中數組的reduce方法

    詳解JavaScript中數組的reduce方法

    js函數中有三個在特定場合很好用的函數:reduce(),map(),filter()。而數組經常用到的方法有push、join、indexOf、slice等等,但是有一個經常被我們忽略的方法:reduce,這個方法簡直強大的不要不要的。下面通過這篇文章來一起學習學習吧。
    2016-12-12
  • JavaScript制作3D旋轉相冊

    JavaScript制作3D旋轉相冊

    這篇文章主要為大家詳細介紹了JavaScript制作3D旋轉相冊,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 微信小程序引用iconfont圖標的方法

    微信小程序引用iconfont圖標的方法

    這篇文章主要介紹了微信小程序引用iconfont圖標的方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-10-10
  • 讓IE8瀏覽器支持function.bind()方法

    讓IE8瀏覽器支持function.bind()方法

    function.bind()方法默認IE8是不支持的,下面有個小技巧可完美解決這個問題,為此疑惑的朋友可以看看
    2014-10-10
  • javascript的回調函數應用示例

    javascript的回調函數應用示例

    回調函數就是一個通過函數指針調用的函數。下面以示例的方式為大家介紹下其具體的使用
    2014-02-02
  • Webpack的dll功能使用

    Webpack的dll功能使用

    這篇文章主要介紹了Webpack的dll功能使用,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Javascript & DHTML上傳文件控件

    Javascript & DHTML上傳文件控件

    首先來做一個實例,批量上傳的UI控件。以后一般做的示例也是以UI控件為主的。都是封裝成Object或者用Function封裝成"Class"類。
    2008-07-07
  • JavaScript數學對象(Math)方法舉例詳解

    JavaScript數學對象(Math)方法舉例詳解

    這篇文章主要給大家介紹了關于JavaScript數學對象(Math)方法的相關資料,Math(數學)對象的作用是執(zhí)行普通的算數任務,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-03-03
  • JavaScript實現前端倒計時效果

    JavaScript實現前端倒計時效果

    這篇文章主要為大家詳細介紹了JavaScript實現前端倒計時效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • 如何在TypeScript使用模塊化以及注意事項詳解

    如何在TypeScript使用模塊化以及注意事項詳解

    在TypeScript中就像在EC5中一樣,任何包含頂級import或export的文件都被認為是一個模塊,下面這篇文章主要給大家介紹了關于如何在TypeScript使用模塊化以及注意事項的相關資料,需要的朋友可以參考下
    2022-10-10

最新評論

巴东县| 四会市| 丹凤县| 奉新县| 千阳县| 土默特右旗| 辽宁省| 枞阳县| 新蔡县| 贡觉县| 旬邑县| 清流县| 长兴县| 南康市| 新乡市| 平湖市| 六枝特区| 高邑县| 子长县| 鄂托克旗| 手游| 咸丰县| 罗平县| 黔南| 盐源县| 那曲县| 霍山县| 宝坻区| 南宁市| 丰宁| 会昌县| 平罗县| 五指山市| 博客| 慈溪市| 平南县| 江阴市| 长沙县| 民县| 商丘市| 雷山县|