JS 深拷貝、淺拷貝

淺拷貝:拷貝一層,深層次的對象級別的就拷貝引用。html

深拷貝:拷貝多層,每一級別的數據都會拷貝出來。數組

JS 變量的數據類型

基本數據類型:number 、 string 、 null 、 undefined 、 boolean 、 symbolbash

引用數據類型:objectfrontend

JS 變量存儲的方式 :

棧(stack): 存儲的是基本數據類型的值和引用數據類型的地址,由系統自動分配內存,系統自動釋放內存。函數

堆(heap): 存儲的是引用數據類型的值,由開發者分配內存(如使用 new 關鍵字進行分配),大小不定,不會自動釋放內存。ui

基本數據類型和引用數據類型區別

值傳遞 和 址傳遞 的區別。this

基本數據類型是值傳遞;引用類型是址傳遞,將存放在棧內存中的地址賦值給接收的變量。
spa

對象深拷貝、淺拷貝

一 . 淺拷貝

1. Object.assign(target, ...sources)prototype

target : 目標對象code

sources : 源對象

let a = {
  age:1
}
let b = Object.assign({}, a);
a.age = 2;
console.log(b.age); //1 
複製代碼

2. { ... obj} 擴展運算符

let a = {
  age: 1
}
let b = {...a};
a.age = 2;
console.log(b.age); //1複製代碼

二 . 深拷貝

1.JSON.parse(JSON.stringify(sourceObj))

let a = {
  age: 1,
  jobs: {
    main:'frontend'
  }
}
let b = JSON.parse(JSON.stringify(a));
a.jobs.main = 'backend';
console.log(b.jobs.main); //'frontend'複製代碼

JSON.parse(JSON.stringify(sourceObj)) 實現深拷貝的侷限:

  • 會忽略 undefined
  • 不能處理函數,會忽略掉函數
  • 不能處理循環引用的對象,會報錯 TypeError

2.使用 loadash 的 cloneDeep() 方法

var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false複製代碼

數組的深拷貝、淺拷貝

一.淺拷貝

淺拷貝,即到數組只有一維的時候,且每一項不是對象的話這樣拷貝看起來和深拷貝效果同樣。

1.Array.prototype.slice()

const a = [1,2,3]
const b = a.slice();
a.push(4);
console.log(a);//[1,2,3,4]
console.log(b);//[1,2,3]複製代碼

淺拷貝一個數組,這樣操做新數組時,就不會改變原數組。

slice不修改原數組,只返回一個淺複製了原數組總的元素的一個新數組。原數組的元素會按照下述規則拷貝:

  • 若是該元素是個對象引用 (不是實際的對象),slice 會拷貝這個對象引用到新的數組裏。兩個對象引用都引用了同一個對象。若是被引用的對象發生改變,則新的和原來的數組中的這個元素也會發生改變。
  • 對於字符串、數字及布爾值來講(不是 String、Number 或者 Boolean 對象),slice 會拷貝這些值到新的數組裏。在別的數組裏修改這些字符串或數字或是布爾值,將不會影響另外一個數組。

若是向兩個數組任一中添加了新元素,則另外一個不會受到影響。

2. Array.prototype.concat()

const a = [1,2,3]
const b = a.concat();
a.push(4);
console.log(a);//[1,2,3,4]
console.log(b);//[1,2,3]複製代碼

concat方法建立一個新的數組,它由被調用的對象中的元素組成,每一個參數的順序依次是該參數的元素(若是參數是數組)或參數自己(若是參數不是數組)。它不會遞歸到嵌套數組參數中。

concat方法不會改變this或任何做爲參數提供的數組,而是返回一個淺拷貝,它包含與原始數組相結合的相同元素的副本。 原始數組的元素將按照以下規則複製到新數組中:

  • 對象引用(而不是實際對象):concat將對象引用複製到新數組中。 原始數組和新數組都引用相同的對象。 也就是說,若是引用的對象被修改,則更改對於新數組和原始數組都是可見的。 這包括也是數組的數組參數的元素。
  • 數據類型如字符串,數字和布爾(不是String,Number 和 Boolean 對象):concat將字符串和數字的值複製到新數組中。

二.深拷貝

和對象的深拷貝方法相同。


參考:https://www.cnblogs.com/Bonnie3449/p/9510431.html

相關文章
相關標籤/搜索