1.背景介紹
什么是棧內(nèi)存和堆內(nèi)存?
JavaScript中的變量的存放有有原始值與引用值之分胜茧,原始值代表了原始的數(shù)據(jù)類型粘优,如Undefined,Null,Number雹顺, String丹墨,Boolean類型的值;而Object嬉愧,F(xiàn)unction带到,Array等類型的值便是引用值了。
棧內(nèi)存中存放的是存儲(chǔ)對(duì)象的地址英染,而堆內(nèi)存中存放的是存儲(chǔ)對(duì)象的具體內(nèi)容揽惹。對(duì)于原始類型的值而言 ,其地址和具體內(nèi)容都存在與棧內(nèi)存中四康;而基于引用類型的值搪搏,其地址存在棧內(nèi)存,其具體內(nèi)容存在堆內(nèi)存中闪金。堆內(nèi)存 與棧內(nèi)存是有區(qū)別的疯溺,棧內(nèi)存運(yùn)行效率比堆內(nèi)存高,空間相對(duì)堆內(nèi)存來(lái)說(shuō)較小哎垦,反之則是堆內(nèi)存的特點(diǎn)囱嫩。所以將構(gòu)造簡(jiǎn) 單的原始類型值放在棧內(nèi)存中,將構(gòu)造復(fù)雜的引用類型值放在堆中而不影響棧的效率漏设。
2.知識(shí)剖析
什么是深拷貝和淺拷貝墨闲?
淺拷貝:復(fù)制一份引用,所有引用對(duì)象都指向一份數(shù)據(jù)郑口,并且都可以修改這份數(shù)據(jù)鸳碧。
深拷貝(復(fù)雜):復(fù)制變量值,對(duì)于非基本類型的變量犬性,則遞歸至基本類型變量后瞻离,再?gòu)?fù)制∑柜桑可以使用slice和concat方法套利。
SLICE和CONCAT使用方法
slice:
語(yǔ)法:arrayObject.slice(start,end)
該方法并不會(huì)修改數(shù)組,而是返回一個(gè)子數(shù)組鹤耍。
start:必需肉迫。規(guī)定從何處開(kāi)始選取。如果是負(fù)數(shù)惰蜜,那么它規(guī)定從數(shù)組尾部開(kāi)始算起的位置昂拂。也就是說(shuō)受神,-1 指最后一個(gè)元素抛猖,-2 指倒數(shù)第二個(gè)元素,以此類推。
end:可選财著。規(guī)定從何處結(jié)束選取联四。該參數(shù)是數(shù)組片斷結(jié)束處的數(shù)組下標(biāo)。如果沒(méi)有指定該參數(shù)撑教,那么切分的數(shù)組包含從 start 到數(shù)組結(jié)束的所有元素朝墩。如果這個(gè)參數(shù)是負(fù)數(shù),那么它規(guī)定的是從數(shù)組尾部開(kāi)始算起的元素伟姐。
concat:
語(yǔ)法:arrayObject.concat(arrayX,arrayX,......,arrayX)
返回一個(gè)新的數(shù)組收苏。該數(shù)組是通過(guò)把所有 arrayX 參數(shù)添加到 arrayObject 中生成的。如果要進(jìn)行 concat() 操作的參 數(shù)是數(shù)組愤兵,那么添加的是數(shù)組中的元素鹿霸,而不是數(shù)組。
arrayX:必需秆乳。該參數(shù)可以是具體的值懦鼠,也可以是數(shù)組對(duì)象∫傺撸可以是任意多個(gè)肛冶。
3.常見(jiàn)問(wèn)題
深拷貝和淺拷貝的運(yùn)用環(huán)境。
4.解決方案
這個(gè)要看大家具體的應(yīng)用扯键,注意到數(shù)組帶來(lái)的影響睦袖。
5.編碼實(shí)戰(zhàn)
淺拷貝的實(shí)現(xiàn),例如:
var arr = ["One","Two","Three"];
var arrto = arr; arrto[1] = "test”;
document.writeln("數(shù)組的原始值:" + arr + "
");//Export:數(shù)組的原始值:One,test,Three
document.writeln("數(shù)組的新值:" + arrto + "
");//Export:數(shù)組的新值:One,test,Three
深拷貝之slice:
var num = ["One","Two","Three"];
var newNum = num.slice(0);
newNum[1] = "haha";
document.writeln("數(shù)組的原始值:" + num + "
");//Export:數(shù)組的原始值:One,Two,Three
document.writeln("數(shù)組的新值:" + newNum + "
");//Export:數(shù)組的新值:One,haha,Three
深拷貝之concat
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
var arr2 = new Array(3)
arr2[0] = "James"
arr2[1] = "Adrew"
arr2[2] = "Martin"
document.write(arr.concat(arr2))//輸出:George,John,Thomas,James,Adrew,Martin;
6.擴(kuò)展思考
對(duì)象的深拷貝
對(duì)象自己寫(xiě)個(gè)迭代函數(shù)就好了荣刑,只需copy到最底層的比如如下代碼扣泊。
function deepCopy(obj,c) {
var c =c || {};
for(var i in obj) {
// 判斷屬性是否為對(duì)象,是的話就進(jìn)一步展開(kāi)
if (typeof(obj[i]) === 'object') {
// 遞歸拷貝
if (obj[i].constructor == Array){
c[i] = [];
deepCopy(obj[i],c[i]);
}
else {
c[i] = {};
deepCopy(obj[i],c[i]);
}
}
else {
c[i] = obj[i];
}
}
return c
};
7.參考文獻(xiàn)
參考一:JavaScript數(shù)組深拷貝和淺拷貝的兩種方法
參考二:原生js對(duì)象的淺拷貝和深拷貝的總結(jié)
8.更多討論
有被淺拷貝坑過(guò)的經(jīng)歷嗎嘶摊?
鳴謝
感謝大家觀看
BY : 彭勇 | 李維文
ppt鏈接:https://ptteng.github.io/PPT/PPT/js-04-arr%20clone.html#/
視頻鏈接:
修真院鏈接:http://www.jnshu.com/login/1/92633351