一.引用類(lèi)型與值類(lèi)型
我們都知道会前,js有兩種基本類(lèi)型,引用類(lèi)型與值類(lèi)型匾竿。引用類(lèi)型的“=”只是拷貝了引用瓦宜,而基本類(lèi)型則是拷貝了值。
值類(lèi)型:數(shù)值岭妖、布爾值临庇、null、undefined昵慌。
引用類(lèi)型:對(duì)象假夺、數(shù)組、函數(shù)斋攀。
一個(gè)簡(jiǎn)單的例子
var a=[1,2,3];
var b=a;
var c=5;
var d=c;
如果a的數(shù)組值變了的話已卷,b也會(huì)跟著變,有的時(shí)候這不是我們想要的蜻韭。
二.從數(shù)組講起
默認(rèn)的數(shù)組賦值是淺拷貝悼尾,那么怎么實(shí)現(xiàn)深拷貝呢柿扣?
1.先來(lái)考慮一維數(shù)組肖方,方法很多闺魏。
var a=[1,2,3];
//第一種,slice會(huì)返回一個(gè)數(shù)組拷貝俯画,其他截取函數(shù)也可以析桥,除了splice
var b=a.slice(0);
//第二種
a.forEach((one,i)=>{b[i]=one});
//第三種,es6的擴(kuò)展運(yùn)算符
var b=[...a]
2.多維數(shù)組
為了通用,直接給Array增加原型方法
Array.prototype.deepCopy = function() {
var temp = [];
this.forEach((one)=>{
//如果子項(xiàng)是數(shù)組就調(diào)用deepCopy
temp.push(one instanceof Array?one.deepCopy:one);
})
return temp;
};
三.擴(kuò)展
數(shù)組中不止會(huì)有數(shù)組艰垂,通常還會(huì)有Object泡仗,對(duì)象數(shù)組是很常見(jiàn)的,所以干脆直接把deepCopy增加到Object上
Object.prototype.deepCopy = function() {
var temp = this instanceof Array ? [] : {};//如果是數(shù)組猜憎,初始化為[],否則初始化維{}
for (var i in this) {//Object的遍歷娩怎,數(shù)組和對(duì)象通用
if (this.hasOwnProperty(i)) {//保證只復(fù)制自帶的屬性
//遇到基本值類(lèi)型,直接復(fù)制胰柑,否則繼續(xù)深拷貝
temp[i] = typeof(this[i]) === 'object' ? this[i].deepCopy() : this[i];
}
}
return temp;
};
測(cè)試一下截亦,沒(méi)問(wèn)題
var a = [{ a: 's' },[1]];
var m = { s: 'h', d: { a: 's' } };
var c = m.deepCopy();
var b = a.deepCopy();
a[0].a = 'm';
a[1][0] = 'm';
m.d.a = 'k';
console.log(a, b, m, c);