堆和棧
棧:系統(tǒng)會(huì)自動(dòng)分配內(nèi)存空間,會(huì)自動(dòng)釋放,存放基本數(shù)據(jù)類型undefined、null、boolean、string、number,棧還有一個(gè)很重要的特性,就是存在棧中的數(shù)據(jù)可以共享。
棧的使用規(guī)則:
棧中首先創(chuàng)建一個(gè)變量為a引用,然后查找棧中是否有3這個(gè)值如果沒(méi)有就將a指向3,到b的時(shí)候查找棧中是否有3這個(gè)值,因?yàn)闂V幸呀?jīng)有3這個(gè) 值就直接將b指向3
var a = 3
var b= 3
堆:動(dòng)態(tài)分配內(nèi)存大小,也不會(huì)自動(dòng)釋放,存放引用類型(function object array)存放的變量實(shí)際保存的是一個(gè)指針,這個(gè)指針指向另一個(gè)位置,每個(gè)空間大小不一樣,要根據(jù)情況進(jìn)行特定的分配。
堆的使用規(guī)則:當(dāng)創(chuàng)建數(shù)組時(shí),就會(huì)在堆內(nèi)存創(chuàng)建一個(gè)數(shù)組對(duì)象,并且在棧內(nèi)存中創(chuàng)建一個(gè)對(duì)數(shù)組的引用(即引用類型在占內(nèi)存中存放的只是該對(duì)象訪問(wèn)的地址,而在堆內(nèi)存中為這個(gè)值分配空間存儲(chǔ))。下面的newArray、oarray為復(fù)合數(shù)據(jù)類型(引用類型),他們的引用變量存放在棧中,指向與存放在堆中的實(shí)際對(duì)象,因?yàn)樗麄兊闹赶蚴且粋€(gè)地址如果任意一個(gè)更改數(shù)值另一個(gè)也會(huì)跟著變化。
var fruit_1="apple";
var fruit_2="orange";
var fruit_3="banana";
var oArray=[fruit_1,fruit_2,fruit_3];
var newArray=oArray;
總結(jié):
棧:存基本數(shù)據(jù)類型,傳值。
堆:存引用類型,傳地址。
淺拷貝
下面的例子中我們聲明了一個(gè)名為a的對(duì)象copy函數(shù)是把a(bǔ)復(fù)制了一遍名為c最后return我們又聲明了一個(gè)b=c因?yàn)樗麄兪且妙愋退詀和b和c的指針指向的是一個(gè)地址,因?yàn)閍.key2是一個(gè)引用類型所以我們給b.key2添加了東西a里面也會(huì)添加。
var a = {
key1:'xiaozhang'
}
function copy(parameter){
var c = {}
for(var i in parameter){
c[i] = parameter[i]
}
return c
}
a.key2=[18]
var b = copy(a)
b.key2.push('打回')
console.log(b.key1) //xiaozhang
console.log(b.key2) //(2) [18, "打回"]
console.log(a.key2) //(2) [18, "打回"]
深拷貝
因?yàn)樯厦娴睦又形覀兏缸訉?duì)象之間產(chǎn)生了相互關(guān)聯(lián),在下面的例子中我們通過(guò)遞歸就可以阻斷賦值之間的關(guān)聯(lián)。
var a = {
key1:'xiaozhang',
}
function Copy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
Copy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
}
a.key2 = ['小輝','小輝'];
var b={};
b = Copy(a,b);
b.key2.push("大輝");
console.log(b.key2); //小輝,小輝,大輝
console.log(a.key2); //小輝,小輝
/*注釋:
當(dāng)我們第一次執(zhí)行copy函數(shù)時(shí)是走的else當(dāng)我們第二次執(zhí)行的時(shí)候走的是if因?yàn)榈诙问莻€(gè)數(shù)組所我們把c賦值了一個(gè)數(shù)組,然后咱if里面執(zhí)行了copy執(zhí)行這次的時(shí)候里面的參數(shù)為數(shù)組和一個(gè)空數(shù)組if循環(huán)每個(gè)都是字符串所以走的是else最后扔出