国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript基礎心法 數據類型

2019-11-19 14:13:59
字體:
來源:轉載
供稿:網友

由于自己是野生程序員,在剛開始學習程序設計的時候沒有在意內存這些基礎知識,導致后來在提到“什么什么是存在棧中的,棧中只是存了一個引用”這樣的話時總是一臉懵逼。。

后來漸漸的了解了一些內存的知識,這部分還是非常有必要了解的。

基本數據結構

棧,只允許在一段進行插入或者刪除操作的線性表,是一種先進后出的數據結構。

堆是基于散列算法的數據結構。

隊列

隊列是一種先進先出(FIFO)的數據結構。

JavaScript中數據類型的存儲

JavaScript中將數據類型分為基本數據類型和引用數據類型,它們其中有一個區別就是存儲的位置不同。

基本數據類型

我們都知道JavaScript中的基本數據類型有:

  • String
  • Number
  • Boolean
  • Undefined
  • Null
  • Symbol(暫時不管)

基本數據類型都是一些簡單的數據段,它們是存儲在棧內存中。

引用數據類型

JavaScript中的引用數據類型有:

  • Array
  • Object

引用數據類型是保存在堆內存中的,然后再棧內存中保存一個對堆內存中實際對象的引用。所以,JavaScript中對引用數據類型的操作都是操作對象的引用而不是實際的對象。

可以理解為,棧內存中保存了一個地址,這個地址和堆內存中的實際值是相關的。

圖解

現在,我們聲明幾個變量試試:

var name="axuebin";var age=25;var job;var arr=[1,2,3];var obj={age:25};

可以通過下圖來表示數據類型在內存中的存儲情況:

此時name,age,job三種基本數據類型是直接存在棧內存中的,而arr,obj在棧內存中只是存了一個地址來表示對堆內存中的引用。

復制

基本數據類型

對于基本數據類型,如果進行復制,系統會自動為新的變量在棧內存中分配一個新值,很容易理解。

引用數據類型

如果對于數組、對象這樣的引用數據類型而言,復制的時候就會有所區別了:

系統也會自動為新的變量在棧內存中分配一個值,但這個值僅僅是一個地址。也就是說,復制出來的變量和原有的變量具有相同的地址值,指向堆內存中的同一個對象。

如果所示,執行了var objCopy=obj之后,obj和objCopy具有相同的地址值,執行堆內存中的同一個實際對象。

這有什么不同呢?

當我修改obj或objCopy時,都會引起另一個變量的改變。

為什么?

為什么基礎數據類型存在棧中,而引用數據類型存在堆中呢?

  1. 堆比棧大,棧比對速度快。
  2. 基礎數據類型比較穩定,而且相對來說占用的內存小。
  3. 引用數據類型大小是動態的,而且是無限的。
  4. 堆內存是無序存儲,可以根據引用直接獲取。

參考文章

理解js內存分配

原始值和引用值

在ECMAScript中,變量可以存放兩種類型的值,即原始值和引用值。
原始值指的就是代表原始數據類型(基本數據類型)的值,即Undefined,Null,Number,String,Boolean類型所表示的值。
引用值指的就是復合數據類型的值,即Object,Function,Array,以及自定義對象,等等

棧和堆

與原始值與引用值對應存在兩種結構的內存即棧和堆
棧是一種后進先出的數據結構,在javascript中可以通過Array來模擬棧的行為

原始值是存儲在棧中的簡單數據,也就是說,他們的值直接存儲在變量訪問的位置。

堆是基于散列算法的數據結構,在javascript中,引用值是存放在堆中的。
引用值是存儲在堆中的對象,也就是說,存儲在變量處的值(即指向對象的變量,存儲在棧中)是一個指針,指向存儲在堆中的實際對象.

例:var obj = new Object(); obj存儲在棧中它指向于new Object()這個對象,而new Object()是存放在堆中的。

那為什么引用值要放在堆中,而原始值要放在棧中,不都是在內存中嗎,為什么不放在一起呢?那接下來,讓我們來探索問題的答案!

首先,我們來看一下代碼:

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);

然后我們來看一下內存分析圖:

變量num,bol,str為基本數據類型,它們的值,直接存放在棧中,obj,person,arr為復合數據類型,他們的引用變量存儲在棧中,指向于存儲在堆中的實際對象。

由上圖可知,我們無法直接操縱堆中的數據,也就是說我們無法直接操縱對象,但我們可以通過棧中對對象的引用來操作對象,就像我們通過遙控機操作電視機一樣,區別在于這個電視機本身并沒有控制按鈕。

現在讓我們來回答為什么引用值要放在堆中,而原始值要放在棧中的問題:

記住一句話:能量是守衡的,無非是時間換空間,空間換時間的問題

堆比棧大,棧比堆的運算速度快,對象是一個復雜的結構,并且可以自由擴展,如:數組可以無限擴充,對象可以自由添加屬性。將他們放在堆中是為了不影響棧的效率。而是通過引用的方式查找到堆中的實際對象再進行操作。相對于簡單數據類型而言,簡單數據類型就比較穩定,并且它只占據很小的內存。不將簡單數據類型放在堆是因為通過引用到堆中查找實際對象是要花費時間的,而這個綜合成本遠大于直接從棧中取得實際值的成本。所以簡單數據類型的值直接存放在棧中。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 岐山县| 伊宁县| 钟山县| 老河口市| 定安县| 航空| 屯昌县| 礼泉县| 南华县| 榆林市| 阳东县| 乡城县| 象州县| 金湖县| 秀山| 通江县| 高唐县| 曲阜市| 浦江县| 中超| 洪江市| 汉阴县| 临江市| 岳阳市| 祁连县| 盱眙县| 宿迁市| 长宁县| 鹤岗市| 嘉定区| 宜黄县| 苍山县| 肥西县| 嵊州市| 松桃| 淮阳县| 鄂托克旗| 鄂温| 玉环县| 舞阳县| 营山县|