国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript中的淺拷貝和深拷貝

ernest.wang / 1929人閱讀

摘要:在中可以通過(guò)添加一個(gè)參數(shù)來(lái)實(shí)現(xiàn)遞歸,調(diào)用就可以實(shí)現(xiàn)一個(gè)深拷貝。利用序列化實(shí)現(xiàn)一個(gè)深拷貝

在JavaScript中,對(duì)于ObjectArray這類引用類型值,當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型值時(shí),這個(gè)值的副本其實(shí)是一個(gè)指針,兩個(gè)變量指向同一個(gè)堆對(duì)象,改變其中一個(gè)變量,另一個(gè)也會(huì)受到影響。

這種拷貝分為兩種情況:拷貝引用和拷貝實(shí)例,也就是我們說(shuō)的淺拷貝和深拷貝

淺拷貝(shallow copy)

拷貝原對(duì)象的引用,這是最簡(jiǎn)單的淺拷貝。

// 對(duì)象
var o1 = {a: 1};
var o2 = o1;

console.log(o1 === o2);  // =>true
o2.a = 2; 
console.log(o1.a); // => 2

// 數(shù)組
var o1 = [1,2,3];
var o2 = o1;

console.log(o1 === o2); // => true
o2.push(4);
console.log(o1); // => [1,2,3,4]

拷貝原對(duì)象的實(shí)例,但是對(duì)其內(nèi)部的引用類型值,拷貝的是其引用,常用的就是如jquey中的$.extend({}, obj); Array.prototype.slice()Array.prototype.concat()都會(huì)返回一個(gè)數(shù)組或者對(duì)象的淺拷貝,舉個(gè)例子:

var o1 = ["darko", {age: 22}];
var o2 = o1.slice(); // 根據(jù)Array.prototype.slice()的特性,這里會(huì)返回一個(gè)o1的淺拷貝對(duì)象

console.log(o1 === o2); // => false,說(shuō)明o2拷貝的是o1的一個(gè)實(shí)例

o2[0] = "lee";
console.log(o1[0]); // => "darko" o1和o2內(nèi)部包含的基本類型值,復(fù)制的是其實(shí)例,不會(huì)相互影響

o2[1].age = 23;
console.log(o1[1].age); // =>23 o1和o2內(nèi)部包含的引用類型值,復(fù)制的是其引用,會(huì)相互影響

可以通過(guò)Array.prototype.slice()jQuery中的$.extend({}, obj)完成對(duì)一個(gè)數(shù)組或者對(duì)象的淺拷貝,我們也可以自己寫一個(gè)簡(jiǎn)單淺拷貝函數(shù)來(lái)加深對(duì)淺拷貝的理解、

// 淺拷貝實(shí)現(xiàn),僅供參考
function shallowClone(source) {
    if (!source || typeof source !== "object") {
        throw new Error("error arguments");
    }
    var targetObj = source.constructor === Array ? [] : {};
    for (var keys in source) {
        if (source.hasOwnProperty(keys)) {
            targetObj[keys] = source[keys];
        }
    }
    return targetObj;
}
深拷貝(deep copy)

深拷貝也就是拷貝出一個(gè)新的實(shí)例,新的實(shí)例和之前的實(shí)例互不影響,深拷貝的實(shí)現(xiàn)有幾種方法,首先我們可以借助jQuery,lodash等第三方庫(kù)完成一個(gè)深拷貝實(shí)例。在jQuery中可以通過(guò)添加一個(gè)參數(shù)來(lái)實(shí)現(xiàn)遞歸extend,調(diào)用$.extend(true, {}, ...)就可以實(shí)現(xiàn)一個(gè)深拷貝。

我們也可以自己實(shí)現(xiàn)一個(gè)深拷貝的函數(shù),通常有兩種方式,一種就是用遞歸的方式來(lái)做,還有一種是利用JSON.stringifyJSON.parse來(lái)做,這兩種方式各有優(yōu)劣,先來(lái)看看遞歸的方法怎么做。

jQuery中的extend方法基本的就是按照這個(gè)思路實(shí)現(xiàn)的,但是沒(méi)有辦法處理源對(duì)象內(nèi)部循環(huán)引用的問(wèn)題,同時(shí)對(duì)Date,F(xiàn)uncion等類型值也沒(méi)有實(shí)現(xiàn)真正的深度復(fù)制,但是這些類型的值在重新定義的時(shí)候一般都是直接覆蓋,所以也不會(huì)對(duì)源對(duì)象產(chǎn)生影響,從一定程度上來(lái)說(shuō)也算是實(shí)現(xiàn)了一個(gè)深拷貝。

// 遞歸實(shí)現(xiàn)一個(gè)深拷貝
function deepClone(source){
   if(!source || typeof source !== "object"){
     throw new Error("error arguments", "shallowClone");
   }
   var targetObj = source.constructor === Array ? [] : {};
   for(var keys in source){
      if(source.hasOwnProperty(keys)){
         if(source[keys] && typeof source[keys] === "object"){
           targetObj[keys] = source[keys].constructor === Array ? [] : {};
           targetObj[keys] = deepClone(source[keys]);
         }else{
           targetObj[keys] = source[keys];
         }
      } 
   }
   return targetObj;
}
// test example
var o1 = {
  arr: [1, 2, 3],
  obj: {
    key: "value"
  },
  func: function(){
    return 1;
  }
};
var o3 = deepClone(o1);
console.log(o3 === o1); // => false
console.log(o3.obj === o1.obj); // => false
console.log(o2.func === o1.func); // => true
  

還有一種實(shí)現(xiàn)深拷貝的方式是利用JSON對(duì)象中的parsestringify,JOSN對(duì)象中的stringify可以把一個(gè)js對(duì)象序列化為一個(gè)JSON字符串,parse可以把JSON字符串反序列化為一個(gè)js對(duì)象,通過(guò)這兩個(gè)方法,也可以實(shí)現(xiàn)對(duì)象的深復(fù)制。

我們從下面的例子就可以看到,源對(duì)象的方法在拷貝的過(guò)程中丟失了,這是因?yàn)?b>在序列化JavaScript對(duì)象時(shí),所有函數(shù)和原型成員會(huì)被有意忽略,這個(gè)實(shí)現(xiàn)可以滿足一些比較簡(jiǎn)單的情況,能夠處理JSON格式所能表示的所有數(shù)據(jù)類型,同時(shí)如果在對(duì)象中存在循環(huán)應(yīng)用的情況也無(wú)法正確處理。

// 利用JSON序列化實(shí)現(xiàn)一個(gè)深拷貝
function deepClone(source){
  return JSON.parse(JSON.stringify(source));
}
var o1 = {
  arr: [1, 2, 3],
  obj: {
    key: "value"
  },
  func: function(){
    return 1;
  }
};
var o2 = deepClone(o1);
console.log(o2); // => {arr: [1,2,3], obj: {key: "value"}}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/86872.html

相關(guān)文章

  • 關(guān)于JavaScript的淺拷貝和深拷貝

    摘要:引用類型值引用類型值是保存在堆內(nèi)存中的對(duì)象,變量保存的只是指向該內(nèi)存的地址,在復(fù)制引用類型值的時(shí)候,其實(shí)只復(fù)制了指向該內(nèi)存的地址。 前言 要理解 JavaScript中淺拷貝和深拷貝的區(qū)別,首先要明白JavaScript的數(shù)據(jù)類型。JavaScript有兩種數(shù)據(jù)類型,基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型。js的基本類型:undefined,null,string,boolean,number,s...

    shenhualong 評(píng)論0 收藏0
  • JS的淺拷貝和深拷貝

    摘要:說(shuō)明外層數(shù)組拷貝的是實(shí)例說(shuō)明元素拷貝是引用深拷貝在堆中重新分配內(nèi)存,并且把源對(duì)象所有屬性都進(jìn)行新建拷貝,拷貝后的對(duì)象與原來(lái)的對(duì)象完全隔離,互不影響。中的方法可以實(shí)現(xiàn)深拷貝,源碼原理也是遞歸使用淺拷貝。 1.淺拷貝 當(dāng)把數(shù)組或?qū)ο蠛?jiǎn)單賦值給其他變量的時(shí)候,實(shí)際上進(jìn)行的是淺拷貝,淺拷貝是拷貝引用,只是將拷貝后的引用指向同一個(gè)對(duì)象實(shí)例,彼此間的操作還會(huì)互相影響。 分為兩種情況:直接拷貝源對(duì)象...

    xeblog 評(píng)論0 收藏0
  • JavaScript的淺拷貝和深拷貝

    摘要:但是進(jìn)行的是淺拷貝,拷貝的是屬性值。對(duì)象展開符深拷貝的實(shí)現(xiàn)方式手動(dòng)復(fù)制轉(zhuǎn)成再轉(zhuǎn)回來(lái)只有可以轉(zhuǎn)成格式的對(duì)象才可以這樣用,像沒(méi)辦法轉(zhuǎn)成沒(méi)被改到使用方法避免相互引用對(duì)象導(dǎo)致死循環(huán),如的情況四參考關(guān)于的淺拷貝和深拷貝 一、理解 淺拷貝只復(fù)制指向某個(gè)對(duì)象的指針,而不復(fù)制對(duì)象本身,新舊對(duì)象還是共享同一塊內(nèi)存。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存,修改新對(duì)象不會(huì)改到原對(duì)象。...

    GeekQiaQia 評(píng)論0 收藏0
  • 實(shí)現(xiàn)JS的淺拷貝和深拷貝

    摘要:淺拷貝和淺拷貝的問(wèn)題,不僅在日常應(yīng)用中需要注意,而且在面試和筆試中也常被用來(lái)考察應(yīng)聘者,屬于文體兩開花的。基本數(shù)據(jù)類型引用數(shù)據(jù)類型等等基本數(shù)據(jù)類型是按值訪問(wèn)的,對(duì)其的拷貝會(huì)直接復(fù)制其值保存在新變量中。方法手工遍歷法方法方法方法方法 淺拷貝和淺拷貝的問(wèn)題,不僅在日常應(yīng)用中需要注意,而且在面試和筆試中也常被用來(lái)考察應(yīng)聘者,屬于文體兩開花的points。 什么是深拷貝和淺拷貝呢? 名稱 ...

    huangjinnan 評(píng)論0 收藏0
  • js的淺拷貝和深拷貝

    摘要:拷貝分為淺拷貝和深拷貝。淺拷貝是引用復(fù)制,深拷貝是完全單純拷貝數(shù)據(jù)的值。所以,這種方法只是簡(jiǎn)單繞過(guò)第一層箱子的引用復(fù)制深拷貝目前比較好的方法就是大法,要么就是自己寫遞歸的深拷貝函數(shù)。附帶深拷貝的自定義函數(shù)源自大佬的 經(jīng)常遇到數(shù)組或?qū)ο蟮纫妙愋妥鳛楹瘮?shù)的參數(shù)的情況,但又不想修改原來(lái)的數(shù)據(jù),這時(shí)候就需要拷貝(基本類型的變量不需要考慮)。拷貝分為淺拷貝和深拷貝。淺拷貝是引用復(fù)制,深拷貝是完...

    jsliang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<