在ECMAScript中,變量可以存放兩種類型的值
原始值
引用類型值
原始值指的是代表原始數(shù)據(jù)類型的值鹿榜,例如:undefined null number string boolean
引用類型指的是復(fù)合類型值橘蜜,例如:object function array 自定義對(duì)象
堆和棧
棧是一種LIFO的數(shù)據(jù)結(jié)構(gòu)驹溃,即后進(jìn)先出,隊(duì)列是一種FIFO的數(shù)據(jù)結(jié)構(gòu)影锈,即先進(jìn)先出
堆是基于散列算法存放數(shù)據(jù)的一種數(shù)據(jù)結(jié)構(gòu)
原始值是存放在棧中的簡(jiǎn)單數(shù)據(jù)段芹务,它們的值直接存儲(chǔ)在變量訪問的位置,例如:
var num = 10; //變量名num和初始化值10都存放在棧中
- 引用值是存放在堆中的對(duì)象鸭廷,引用值的變量名是一個(gè)存放在棧中指針枣抱,指向堆中的引用值對(duì)象,例如:
var obj = new object(); //變量名obj存放在棧中辆床,而它指向的object()對(duì)象是存放在堆中的
為什么原始值要放在棧中佳晶,引用值要放在堆中?
- 先看一段代碼
function Person(id,name,age){
this.id = id;
this.name = name;
this.age = age;
}
var num = 10;
var bol = true;
var str = "abc";
var obj = new Object();
var arr = ['a','b','c'];
var person = new Person(100,"笨蛋的座右銘",25);
- 內(nèi)存分析
原始類型變量num bol str的變量名和內(nèi)容都存放在棧中
引用類型變量obj arr person的變量名作為指針存放在棧中讼载,指向堆中的變量?jī)?nèi)容
由上圖可以看出轿秧,我們不能直接操作堆中的數(shù)據(jù),也就是說不能直接操作對(duì)象咨堤,但我們可以通過棧中存放的變量指針來進(jìn)行操作
- 為什么要分堆和棧
堆比棧大菇篡,棧比堆的運(yùn)算速度快,對(duì)象是一個(gè)復(fù)雜的結(jié)構(gòu),并且可以自由擴(kuò)展一喘,如:數(shù)組可以無(wú)限擴(kuò)充驱还,對(duì)象可以自由添加屬性。將他們放在堆中是為了不影響棧的效率。而是通過引用的方式查找到堆中的實(shí)際對(duì)象再進(jìn)行操作议蟆。相對(duì)于簡(jiǎn)單數(shù)據(jù)類型而言闷沥,簡(jiǎn)單數(shù)據(jù)類型就比較穩(wěn)定,并且它只占據(jù)很小的內(nèi)存咪鲜。不將簡(jiǎn)單數(shù)據(jù)類型放在堆是因?yàn)橥ㄟ^引用到堆中查找實(shí)際對(duì)象是要花費(fèi)時(shí)間的狐赡,而這個(gè)綜合成本遠(yuǎn)大于直接從棧中取得實(shí)際值的成本。所以簡(jiǎn)單數(shù)據(jù)類型的值直接存放在棧中
總結(jié)
兩種變量類型:原始值和引用類型值
變量在內(nèi)存中的存放位置分為堆和棧