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...