物件引用 淺層拷貝與深層拷貝的區別

2021-09-26 07:47:47 字數 2109 閱讀 5244

var a = 

var b = a ;

a===b // true

b.name = 'zhangsan'

a.name //'zhangan'

上述**中,使用了=進行賦值,於是b指向了a所指向的棧的物件,也就是a與b指向了同乙個棧物件,所以在對b.name賦值時,a.name也發生了變化。為了避免上面的情況,可以對物件進行拷貝,**如下:

var a = 

var b = object.assign({}, a)

a===b // false

b.name = 'zhangsan'

a.name //'wanger'

上面**將原始物件拷貝到乙個空物件,就得到了原始物件的轉殖,這時候a與b指向的是不同的棧物件,所以對b.name重新複製也不會影響到a.name。但是如果a.name是乙個物件的引用,而不是乙個字串,那麼上面的**也會遇到一些問題,參考如下**:

var a = }

var b = object.assign({}, a)

a===b // false

b.name.firstname = 'zhang'

a.name.firstname //'zhang'

b.name.firstname又影響到了a.name.firstname,這是因為object.assign()方法只是淺層拷貝,a.name是乙個棧物件的引用,賦值給b時,b.name也同樣是這個棧物件的引用,很多時候,我們不想讓這種事情發生,所以我們就需要用到物件的深拷貝。

通常情況下,我們可以使用json.parse()與 json.stringify()實現物件的深轉殖,如下:

var clone = function (obj)
var clone = function (obj) 

var a = ,b:,c:[1,2,3],d:"wanger",e:new

date(),f:null,g:undefined}

var b = clone(a)

列印如下:

我們發現,上述的方法會忽略值為function以及undefied的字段,而且對date型別的支援也不太友好。

function

person (name)

var wanger = new person('王二')

var newwanger = clone(wanger)

wanger.constructor === person // true

newwanger.constructor === object

// true

列印如下:

我們發現,轉殖的物件的建構函式已經變成了object,而原來的物件的構造是person。

var clone = function (obj) 

} return newobj;

};

這裡有三點需要注意:

1、用new obj.constructor ()建構函式新建乙個空的物件,而不是使用{}或者,這樣可以保持原形鏈的繼承;

2、用obj.hasownproperty(key)來判斷屬性是否來自原型鏈上,因為for..in..也會遍歷其原型鏈上的可列舉屬性。

3、上面的函式用到遞迴演算法,在函式有名字,而且名字以後也不會變的情況下,這樣定義沒有問題。但問題是這個函式的執行與函式名 factorial 緊緊耦合在了一起。為了消除這種緊密耦合的現象,需要使用arguments.callee

2017-10-03新增,之前沒有考慮正則物件的問題,這裡再做一下修改:

var clone = function (obj) 

} return newobj;

};

JS物件的引用,物件的拷貝

除了基本型別跟null,物件之間的賦值,只是將位址指向同乙個,而不是真正意義上的拷貝 將乙個物件賦值給另外乙個物件。var a 1,2,3 var b a b.push 4 b中新增了乙個4 alert a a變成了 1,2,3,4 自定義物件 var obj var obj2 obj obj2.a...

JavaScript物件的引用,物件的拷貝

除了基本型別跟null,物件之間的賦值,只是將位址指向同乙個,而不是真正意義上的拷貝 將乙個物件賦值給另外乙個物件。var a 1,2,3 var b a b.push 4 b中新增了乙個4 alert a a變成了 1,2,3,4 自定義物件 var obj var obj2 obj obj2.a...

JS物件的引用,物件的拷貝

除了基本型別跟null,物件之間的賦值,只是將位址指向同乙個,而不是真正意義上的拷貝 將乙個物件賦值給另外乙個物件。var a 1,2,3 var b a b.push 4 b中新增了乙個4 alert a a變成了 1,2,3,4 自定義物件 var obj var obj2 obj obj2.a...