數(shù)組的淺拷貝:
如果是數(shù)組,我們可以利用數(shù)組的一些方法,比如 slice啊鸭,concat 方法返回一個(gè)新數(shù)組的特性來實(shí)現(xiàn)拷貝发绢,但假如數(shù)組嵌套了對(duì)象或者數(shù)組的話硬耍,使用 concat 方法克隆并不完整, 如果數(shù)組元素是基本類型朴摊,就會(huì)拷貝一份默垄,互不影響,而如果是對(duì)象或數(shù)組甚纲,就會(huì)只拷貝對(duì)象和數(shù)組的引用口锭,這樣我們無論在新舊數(shù)組進(jìn)行了修改,兩者都會(huì)發(fā)生變化,我們把這種復(fù)制引用的拷貝方法稱為淺拷貝鹃操,
深拷貝就是指完全的拷貝一個(gè)對(duì)象韭寸,即使嵌套了對(duì)象,兩者也互相分離荆隘,修改一個(gè)對(duì)象的屬性恩伺,不會(huì)影響另一個(gè)
如何深拷貝一個(gè)數(shù)組
1、這里介紹一個(gè)技巧椰拒,不僅適用于數(shù)組還適用于對(duì)象晶渠!那就是:
var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
var new_arr = JSON.parse( JSON.stringify(arr) );
console.log(new_arr);
原理是 JOSN 對(duì)象中的 stringify 可以把一個(gè) js 對(duì)象序列化為一個(gè) JSON 字符串,parse 可以把 JSON 字符串反序列化為一個(gè) js 對(duì)象燃观,通過這兩個(gè)方法褒脯,也可以實(shí)現(xiàn)對(duì)象的深復(fù)制。
但是這個(gè)方法不能夠拷貝函數(shù)
淺拷貝的實(shí)現(xiàn):
以上三個(gè)方法 concat,slice ,JSON.stringify 都是技巧類缆毁,根據(jù)實(shí)際項(xiàng)目情況選擇使用番川,我們可以思考下如何實(shí)現(xiàn)一個(gè)對(duì)象或數(shù)組的淺拷貝,遍歷對(duì)象脊框,然后把屬性和屬性值都放在一個(gè)新的對(duì)象里即可
var shallowCopy = function(obj) {
// 只拷貝對(duì)象
if (typeof obj !== 'object') return;
// 根據(jù) obj 的類型判斷是新建一個(gè)數(shù)組還是對(duì)象
var newObj = obj instanceof Array ? [] : {};
// 遍歷 obj颁督,并且判斷是 obj 的屬性才拷貝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
深拷貝的實(shí)現(xiàn)
那如何實(shí)現(xiàn)一個(gè)深拷貝呢?說起來也好簡(jiǎn)單浇雹,我們?cè)诳截惖臅r(shí)候判斷一下屬性值的類型沉御,
如果是對(duì)象,我們遞歸調(diào)用深拷貝函數(shù)不就好了~
var deepCopy = function(obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}