理解Javascript_01_理解內(nèi)存分配原理分析
更新時間:2010年10月11日 22:52:45 作者:
在正式開始之前,我想先說兩句,理解javascript系列博文是通過帶領(lǐng)大家分析javascript執(zhí)行時的內(nèi)存分配情況,來解釋javascript原理,具體會涵蓋javascript預(yù)加載,閉包原理,面象對象,執(zhí)行模型,對象模型...,文章的視角很特別,也非常深入,希望大家能接受這種形式,并提供寶貴意見。
原始值和引用值
在ECMAScript中,變量可以存放兩種類型的值,即原始值和引用值。
原始值指的就是代表原始數(shù)據(jù)類型(基本數(shù)據(jù)類型)的值,即Undefined,Null,Number,String,Boolean類型所表示的值。
引用值指的就是復(fù)合數(shù)據(jù)類型的值,即Object,Function,Array,以及自定義對象,等等
棧和堆
與原始值與引用值對應(yīng)存在兩種結(jié)構(gòu)的內(nèi)存即棧和堆
棧是一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),在javascript中可以通過Array來模擬棧的行為
var arr = []; //創(chuàng)建一個棧
arr.push("apple");//壓入元素"apple" ["apple"]
arr.push("orange");//壓入元素"orange" ["apple","orange"]
arr.pop();//彈出"orange" ["apple"]
arr.push("banana");//壓入元素"banana" ["apple","banana"]
我們來看一下,與之對應(yīng)的內(nèi)存圖:

原始值是存儲在棧中的簡單數(shù)據(jù)段,也就是說,他們的值直接存儲在變量訪問的位置。
堆是存放數(shù)據(jù)的基于散列算法的數(shù)據(jù)結(jié)構(gòu),在javascript中,引用值是存放在堆中的。
引用值是存儲在堆中的對象,也就是說,存儲在變量處的值(即指向?qū)ο蟮淖兞?,存儲在棧中)是一個指針,指向存儲在堆中的實際對象.
例:var obj = new Object(); obj存儲在棧中它指向于new Object()這個對象,而new Object()是存放在堆中的。
那為什么引用值要放在堆中,而原始值要放在棧中,不都是在內(nèi)存中嗎,為什么不放在一起呢?那接下來,讓我們來探索問題的答案!
首先,我們來看一下代碼:
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,"jxl",22);
然后我們來看一下內(nèi)存分析圖:

變量num,bol,str為基本數(shù)據(jù)類型,它們的值,直接存放在棧中,obj,person,arr為復(fù)合數(shù)據(jù)類型,他們的引用變量存儲在棧中,指向于存儲在堆中的實際對象。
由上圖可知,我們無法直接操縱堆中的數(shù)據(jù),也就是說我們無法直接操縱對象,但我們可以通過棧中對對象的引用來操作對象,就像我們通過遙控機(jī)操作電視機(jī)一樣,區(qū)別在于這個電視機(jī)本身并沒有控制按鈕。
現(xiàn)在讓我們來回答為什么引用值要放在堆中,而原始值要放在棧中的問題:
記住一句話:能量是守衡的,無非是時間換空間,空間換時間的問題
堆比棧大,棧比堆的運(yùn)算速度快,對象是一個復(fù)雜的結(jié)構(gòu),并且可以自由擴(kuò)展,如:數(shù)組可以無限擴(kuò)充,對象可以自由添加屬性。將他們放在堆中是為了不影響棧的效率。而是通過引用的方式查找到堆中的實際對象再進(jìn)行操作。相對于簡單數(shù)據(jù)類型而言,簡單數(shù)據(jù)類型就比較穩(wěn)定,并且它只占據(jù)很小的內(nèi)存。不將簡單數(shù)據(jù)類型放在堆是因為通過引用到堆中查找實際對象是要花費(fèi)時間的,而這個綜合成本遠(yuǎn)大于直接從棧中取得實際值的成本。所以簡單數(shù)據(jù)類型的值直接存放在棧中。
總結(jié):
程序很簡單,但它是一切的根本,基礎(chǔ)是最重要的,因為摩天大廈也是一塊磚一塊瓦的搭建起來的。
內(nèi)存是程序執(zhí)行的根本,搞懂了內(nèi)存,就等于搞懂了一切。
心血之作,鼓勵一下自已,加油!
參考:
JavaScript高級程序設(shè)計
在ECMAScript中,變量可以存放兩種類型的值,即原始值和引用值。
原始值指的就是代表原始數(shù)據(jù)類型(基本數(shù)據(jù)類型)的值,即Undefined,Null,Number,String,Boolean類型所表示的值。
引用值指的就是復(fù)合數(shù)據(jù)類型的值,即Object,Function,Array,以及自定義對象,等等
棧和堆
與原始值與引用值對應(yīng)存在兩種結(jié)構(gòu)的內(nèi)存即棧和堆
棧是一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),在javascript中可以通過Array來模擬棧的行為
復(fù)制代碼 代碼如下:
var arr = []; //創(chuàng)建一個棧
arr.push("apple");//壓入元素"apple" ["apple"]
arr.push("orange");//壓入元素"orange" ["apple","orange"]
arr.pop();//彈出"orange" ["apple"]
arr.push("banana");//壓入元素"banana" ["apple","banana"]
我們來看一下,與之對應(yīng)的內(nèi)存圖:

原始值是存儲在棧中的簡單數(shù)據(jù)段,也就是說,他們的值直接存儲在變量訪問的位置。
堆是存放數(shù)據(jù)的基于散列算法的數(shù)據(jù)結(jié)構(gòu),在javascript中,引用值是存放在堆中的。
引用值是存儲在堆中的對象,也就是說,存儲在變量處的值(即指向?qū)ο蟮淖兞?,存儲在棧中)是一個指針,指向存儲在堆中的實際對象.
例:var obj = new Object(); obj存儲在棧中它指向于new Object()這個對象,而new Object()是存放在堆中的。
那為什么引用值要放在堆中,而原始值要放在棧中,不都是在內(nèi)存中嗎,為什么不放在一起呢?那接下來,讓我們來探索問題的答案!
首先,我們來看一下代碼:
復(fù)制代碼 代碼如下:
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,"jxl",22);
然后我們來看一下內(nèi)存分析圖:

變量num,bol,str為基本數(shù)據(jù)類型,它們的值,直接存放在棧中,obj,person,arr為復(fù)合數(shù)據(jù)類型,他們的引用變量存儲在棧中,指向于存儲在堆中的實際對象。
由上圖可知,我們無法直接操縱堆中的數(shù)據(jù),也就是說我們無法直接操縱對象,但我們可以通過棧中對對象的引用來操作對象,就像我們通過遙控機(jī)操作電視機(jī)一樣,區(qū)別在于這個電視機(jī)本身并沒有控制按鈕。
現(xiàn)在讓我們來回答為什么引用值要放在堆中,而原始值要放在棧中的問題:
記住一句話:能量是守衡的,無非是時間換空間,空間換時間的問題
堆比棧大,棧比堆的運(yùn)算速度快,對象是一個復(fù)雜的結(jié)構(gòu),并且可以自由擴(kuò)展,如:數(shù)組可以無限擴(kuò)充,對象可以自由添加屬性。將他們放在堆中是為了不影響棧的效率。而是通過引用的方式查找到堆中的實際對象再進(jìn)行操作。相對于簡單數(shù)據(jù)類型而言,簡單數(shù)據(jù)類型就比較穩(wěn)定,并且它只占據(jù)很小的內(nèi)存。不將簡單數(shù)據(jù)類型放在堆是因為通過引用到堆中查找實際對象是要花費(fèi)時間的,而這個綜合成本遠(yuǎn)大于直接從棧中取得實際值的成本。所以簡單數(shù)據(jù)類型的值直接存放在棧中。
總結(jié):
程序很簡單,但它是一切的根本,基礎(chǔ)是最重要的,因為摩天大廈也是一塊磚一塊瓦的搭建起來的。
內(nèi)存是程序執(zhí)行的根本,搞懂了內(nèi)存,就等于搞懂了一切。
心血之作,鼓勵一下自已,加油!
參考:
JavaScript高級程序設(shè)計
您可能感興趣的文章:
相關(guān)文章
javascript實現(xiàn)焦點滾動圖效果 具體方法
以下JS代碼實現(xiàn)了焦點滾動圖的效果方法,有需要的朋友可以參考一下2013-06-06微信小程序?qū)崿F(xiàn)3D輪播圖效果(非swiper組件)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)3D輪播圖效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-09-09