JavaScript 的引用和複製

首先咱們看下面這個例子:函數

let age = 18;
let age2 = age;
console.log(age, age2);
複製代碼

咱們會獲得如下的值:ui

18 18
複製代碼

這個相信你們都能很好理解。spa

那麼若是咱們改變 age 的值呢?輸出會有什麼變化?code

age = 20;
console.log(age, age2);
複製代碼

咱們會獲得:對象

20 18
複製代碼

看到這裏你們就奇怪了,上面的結果都很正常啊。ip

但在 JavaScript 中是有例外的,對於普通數據類型如 integer,string,boolean 能夠經過 = 來複制這個變量,但對於 array 和 object 數據類型,= 只能起到引用的效果。內存

你們能夠看下面這個例子:string

let arr = ['wes', 'bob', 'faker'];
let arr2 = arr;
console.log(arr2, arr);
arr[2] = 'dean';
console.log(arr2, arr);
複製代碼

獲得的結果是:console

["wes", "bob", "faker"] ["wes", "bob", "faker"]
["wes", "bob", "dean"] ["wes", "bob", "dean"]
複製代碼

咱們會發現隨着 arr 的改變,arr2 也會跟着改變。ast

說明 arr2 並無複製 arr 的值,只是引用了它,它們都指向同一個內存中的值。

object 也是同樣的:

let obj = {
    age: 19,
    name: 'like',
    last: 'jam'
};
let obj2 = obj;
console.log(obj, obj2);
obj.age = 50;
console.log(obj, obj2);
複製代碼

獲得的結果是:

{age: 19, name: "like", last: "jam"} {age: 19, name: "like", last: "jam"}
{age: 50, name: "like", last: "jam"} {age: 50, name: "like", last: "jam"}
複製代碼

那麼如何複製 array 和 object 呢?

複製 array 的方法:

方法1:

let arr2 = [].concat(arr);
複製代碼

方法2:

let arr2 = arr.slice();
複製代碼

方法3:

let arr2 = Array.from(arr);
複製代碼

方法4:

let arr2 = [...arr];
複製代碼

通常咱們比較經常使用的是方法3和方法4,方法1和方法2比較取巧,但都是能夠達到複製 array 的目的的。

ps: [...arr] 是 ES6 中的方法。

複製 object 的方法:

方法1:

let obj2 = Object.assign({}, obj);
複製代碼

方法2:

let obj2 = {...obj};
複製代碼

方法1和方法2都有個缺點,它們只會複製對象的第一層。

看下面這個例子:

let obj = {
    number: 12,
    name: {
        first: 'bob',
        last: 'evil'
    }
};
let obj2 = Object.assign({}, obj);
obj.number = 50;
console.log(obj, obj2);
複製代碼

咱們會獲得下面的結果:

obj = {
    number: 50,
    name: {
        first: 'bob',
        last: 'evil'
    }
}

obj2 = {
    number: 12,
    name: {
        first: 'bob',
        last: 'evil'
    }
}
複製代碼

但若是咱們改變第二層的值:

obj.name.first = 'sam';
console.log(obj, obj2);
複製代碼
obj = {
    number: 50,
    name: {
        first: 'sam',
        last: 'evil'
    }
}

obj2 = {
    number: 12,
    name: {
        first: 'sam',
        last: 'evil'
    }
}
複製代碼

咱們發現對象第二層依舊是引用的,並無實現複製。

要複製一個完整的 object 能夠使用第三方函數庫 lodash ,它提供了 clone 和 deepclone 徹底能夠知足平常的需求。

相關文章
相關標籤/搜索