TypeScript
????TypeScript是一種由微軟開發(fā)的自由和開源的編程語言。它是JavaScript的一個(gè)超集,而且本質(zhì)上向這個(gè)語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊?/a>藏澳。
????TypeScript擴(kuò)展了JavaScript的語法娇豫,所以任何現(xiàn)有的JavaScript程序可以不加改變的在TypeScript下工作。TypeScript是為大型應(yīng)用之開發(fā)而設(shè)計(jì)脂倦,而編譯時(shí)它產(chǎn)生 JavaScript 以確保兼容性番宁。
????TypeScript 支持為已存在的 JavaScript 庫添加類型信息的頭文件,擴(kuò)展了它對于流行的庫如jQuery赖阻,MongoDB蝶押,Node.js和 D3.js 的好處。
TS中的淺拷貝與深拷貝
????所謂深拷貝與淺拷貝火欧,是圍繞引用類型變量的拷貝進(jìn)行的討論
????在TypeScript中棋电,變量分為基本類型和引用類型兩種。其本質(zhì)區(qū)別是不可變性苇侵,基本類型是不可變的离陶,而引用類型是可變的。
????所謂基本類型的不可變性衅檀,我們可以舉個(gè)例子
let a = 1;
let b = 1;
a++;
console.log("a的值是:"+a,"b的值是:"+b);
//打印結(jié)果如下:
/*
a的值是2招刨,b的值是1
*/
聲明一個(gè)變量a,并為其賦值1哀军,這時(shí)內(nèi)存中開辟出一片區(qū)域用來儲(chǔ)存1沉眶。此時(shí)聲明了一個(gè)變量b打却,也為b賦值1。當(dāng)執(zhí)行a++時(shí)谎倔,基本類型的不可變性就體現(xiàn)出來柳击,a++的值應(yīng)該為2,但是這個(gè)值并不會(huì)將原來儲(chǔ)存1的那片內(nèi)存覆蓋掉片习,而是再開辟一片內(nèi)存來存儲(chǔ)2捌肴。所以對于這個(gè)1來講,他是永遠(yuǎn)不可變的藕咏。
而對于引用變量則不同状知,因?yàn)槠浯鎯?chǔ)的是只想某個(gè)內(nèi)存區(qū)域的地址,所以其修改時(shí)直接操作在內(nèi)存上的孽查,這就導(dǎo)致了深拷貝和淺拷貝問題的出現(xiàn)饥悴。
- 淺拷貝
let shallowA = {
x: 1,
y: -1
}
let shallowB = shallowA;
shallowA.x++;
console.log("shallowA.x==="+shallowA.x,"shallowB.x==="+shallowB.x,)
//打印結(jié)果如下:
shallowA.x === 2
shallowB.x === 2
????這就是最簡單的淺拷貝,其效果十分明顯盲再,對拷貝源的操作西设,會(huì)直接體現(xiàn)在拷貝目標(biāo)上,因?yàn)檫@個(gè)賦值行為的本質(zhì)是內(nèi)存地址的賦值答朋,所以他們指向了同一片內(nèi)存區(qū)域贷揽。
????淺拷貝十分容易,也十分常見梦碗,但卻無法滿足需求擒滑,假如我們需要獲得與拷貝源完全相同,卻又不會(huì)互相影響的對象叉弦,應(yīng)該怎么辦呢丐一。
- Object.assign()
????TypeScript為我們提供了一種十分好用的方法,Object.assign(target, ...source)方法assign方法接受多個(gè)參數(shù)淹冰,第一個(gè)參數(shù)target為拷貝目標(biāo)库车,剩余參數(shù)...source是拷貝源。此方法可以將...source中的屬性復(fù)制到target中樱拴,同名屬性會(huì)進(jìn)行覆蓋棍潘,并且在復(fù)制過程中實(shí)現(xiàn)了'偽'深拷貝
let shallowA = {
a: 1,
b: 2,
c: {
d: 1,
}
}
let shallowB = {};
Object.assign(shallowB, shallowA);
shallowA.a++;
console.log("shallowA.a==="+shallowA.a,"shallowB.a==="+shallowB.a,);
//打印結(jié)果如下:
shallowA.a === 2
shallowB.a === 1
表面上看再沧,好像已經(jīng)實(shí)現(xiàn)了深拷貝的效果,對shallowA.a進(jìn)行的操作并沒有體現(xiàn)在shallowA.a中,但是呢,關(guān)鍵的時(shí)候來了棺蛛,這也是我今天為什么要寫這個(gè)博客的主要問題所在挟阻。
shallowA.c.d++;
console.log("shallowA.c.d==="+shallowA.c.d,"shallowB.c.d==="+shallowB.c.d);
//打印結(jié)果如下:
shallowA.c.d === 2
shallowB.c.d === 2
從上面的打印結(jié)果看出伐债,Object.assign()的拷貝類型十分明顯了,這是一種可以對非嵌套對象進(jìn)行深拷貝的方法,如果對象中出現(xiàn)嵌套情況,那么其對被嵌套對象的行為就成了普通的淺拷貝.
在今天的開發(fā)中我也遇到了此問題趣兄。從后臺(tái)返回的數(shù)據(jù)是一個(gè)數(shù)組A,數(shù)組A里面又包含了B對象,B對象中又包含數(shù)組C履怯,數(shù)組C里面又含有對象D回还。
而我又將數(shù)組A拷貝三份。放進(jìn)一個(gè)大數(shù)組叹洲,形如【A1,A2,A3】;其中A1柠硕,A2,A3,都是A數(shù)組拷貝過來运提。當(dāng)我操作A1數(shù)組里面的A.B.C.D的時(shí)候蝗柔,發(fā)現(xiàn),A2,與A3的D對象也跟著改變民泵。
那么癣丧,應(yīng)該如何拷貝才能達(dá)到操作A1中的D對象,而A2與A3的D對象不變呢洪灯,也就是如何實(shí)現(xiàn)完完全全的深拷貝呢坎缭?
stringify()和parse()
JSON對象中包含兩個(gè)方法, stringify()和parse(),前者可以將對象JSON化,而后者可以將JSON格式轉(zhuǎn)換為對象.這是一種可以實(shí)現(xiàn)深拷貝的方法.但這種方法的缺陷是會(huì)破壞原型鏈,并且無法拷貝屬性值為function的屬性所以如果只是想單純復(fù)制一個(gè)嵌套對象,可以使用此方法竟痰。
let shallowA = {
a: 1,
b: {
c: 1
}
}
let shallowB = JSON.parse(JSON.stringify(shallowA));
shallowA.b.c++;
console.log("shallowA.b.c==="+shallowA.b.c"shallowB.b.c==="+shallowB.b.c);
//打印結(jié)果如下:
shallowA.b.c===2签钩;
shallowB.b.c===1;
由此可見坏快,我們已經(jīng)實(shí)現(xiàn)了對象的完全深拷貝铅檩。
我的問題也就迎刃而解;接下來莽鸿,就可以開心的開發(fā)接下來的功能了昧旨。。祥得。兔沃。不解決此問題真的木辦法往下繼續(xù)了。