中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java深拷貝與淺拷貝的區別是什么

發布時間:2021-11-06 11:15:55 來源:億速云 閱讀:173 作者:iii 欄目:web開發

這篇文章主要介紹“Java深拷貝與淺拷貝的區別是什么”,在日常操作中,相信很多人在Java深拷貝與淺拷貝的區別是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java深拷貝與淺拷貝的區別是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

如何區分深拷貝與淺拷貝,大白話來說,就是假設B復制了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,拿人手短,如果B沒變,那就是深拷貝,自食其力。

先看一個例子:

let a = [0, 1, 2, 3, 4],
  b = a;
console.log(a === b); // true
a[0] = 9;
console.log(a, b);   // [9, 1, 2, 3, 4]

Java深拷貝與淺拷貝的區別是什么

吆哈,明明b復制了a,為啥修改數組a,數組b也跟著變了??

基本數據類型和復雜(引用)數據類型?

基本數據類型:number, string, boolean, null, undefined, symbol

引用數據類型:Object類,有常規名值對的無須對象{a: 1}, 數組[1, 2, 3],函數等。

而這兩類數據存儲方式分別是這樣的:

1. 基本類型–名值存儲在棧內存中,例如let a=1;

Java深拷貝與淺拷貝的區別是什么

當你b=a復制時,棧內存會新開辟一個內存,例如這樣:

Java深拷貝與淺拷貝的區別是什么

所以當你此時修改a=2,對b并不會造成影響,因為此時的b已自食其力,翅膀硬了,不受a的影響了。當然,let a=1, b=a; 雖然b不受a影響,但這也算不上深拷貝,因為深拷貝本身只針對較為復雜的object類型數據。

    2.引用數據類型–名存在棧內存中,值存在于堆內存中,但是棧內存會提供一個引用的地址指向堆內存中的值,我們以上面淺拷貝的例子畫個圖:

Java深拷貝與淺拷貝的區別是什么

當b=a進行拷貝時,其實復制的是a的引用地址,而并非堆里面的值。

Java深拷貝與淺拷貝的區別是什么

而當我們a[0]=1時進行數組修改時,由于a與b指向的是同一個地址,所以自然b也受了影響,這就是所謂的淺拷貝了。

Java深拷貝與淺拷貝的區別是什么

那,要是在堆內存中也開辟一個新的內存專門為b存放值,就像基本類型那樣,豈不就達到深拷貝的效果了。

Java深拷貝與淺拷貝的區別是什么

實現簡單的深拷貝方法?

先看幾個簡單例子?

1.slice() 方法

// 先看一個js中的方法slice() 方法可從已有的數組中返回選定的元素。
    // 該方法并不會修改數組,而是返回一個子數組。arrayObject.slice(start,end)
    let a1 = [1, 2, 3, 4],
      b2 = a1.slice();
      a1[0] = 2;
    console.log(a1, b2);

如上圖所述,slice()方法看似是一個深拷貝的方法了!在改造一下上述代碼片段,我們再看 ????

let a1 = [1, 2, [5,6], 3, 4],
      b2 = a1.slice();
      a1[0] = 2;
      a1[2][0] = 9;
    console.log(a1, b2);

拷貝的不徹底,b對象的一級屬性確實不受影響了,但是二級屬性還是沒能拷貝成功,仍然脫離不了a的控制,說明slice根本不是真正的深拷貝。

2.遞歸

// 簡單深拷貝封裝遞歸函數
    function deepClone(obj) {
      let objClone = Array.isArray(obj) ? [] : {};
      if (obj && typeof obj === "object") {
        for (key in obj) {
          if (obj.hasOwnProperty(key)) { // 注:hasOwnProperty()方法
            //判斷obj子元素是否為對象,如果是,遞歸復制
            console.log(obj[key])
            if (obj[key] && typeof obj[key] === "object") {
              objClone[key] = deepClone(obj[key]);
            } else {
              //如果不是,簡單復制
              objClone[key] = obj[key];
            }
          }
        }
      }
      return objClone;
    }
    let arr = [1, 2, [5, 6], 4],
      b1 = deepClone(arr);
    arr[2][0] = 9;
    console.log(arr, b1);
    // 跟之前想象的一樣,現在b脫離了a的控制,不再受a影響了。這里再次強調,深拷貝,是拷貝對象各個層級的屬性。

Java深拷貝與淺拷貝的區別是什么

注:hasOwnProperty() 官方 MDN講解方法會返回一個布爾值,指示對象自身屬性中是否具有指定的屬性(也就是,是否有指定的鍵)。

3. 除了遞歸,我們還可以借用JSON對象的parse和stringify。

function deepClone(obj){
    let _obj = JSON.stringify(obj),
        objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

Java深拷貝與淺拷貝的區別是什么

4. 除了上面兩種方法之外,我們還可以借用JQ的extend方法。

$.extend( [deep ], target, object1 [, objectN ] )

deep表示是否深拷貝,為true為深拷貝,為false,則為淺拷貝

target Object類型 目標對象,其他對象的成員屬性將被附加到該對象上。

object1 objectN可選。 Object類型 第一個以及第N個被合并的對象。

let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

Java深拷貝與淺拷貝的區別是什么

到此,關于“Java深拷貝與淺拷貝的區別是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永年县| 汉源县| 莱芜市| 和政县| 昆山市| 金秀| 五常市| 邛崃市| 象州县| 泰来县| 体育| 化州市| 苏尼特左旗| 兴山县| 乌拉特前旗| 绥德县| 石家庄市| 长垣县| 信宜市| 沙湾县| 隆化县| 三明市| 博白县| 金塔县| 都安| 青河县| 汉中市| 万山特区| 太原市| 思南县| 儋州市| 剑阁县| 长岛县| 准格尔旗| 台北市| 丹凤县| 永康市| 德安县| 河间市| 五华县| 西乌珠穆沁旗|