首頁 >web前端 >js教程 >js基礎心法之資料類型

js基礎心法之資料類型

青灯夜游
青灯夜游轉載
2018-10-09 15:05:332392瀏覽

一個很基礎的知識點,這篇主要是介紹JavaScript中基本資料型別和引用資料型別是如何儲存的,需要的朋友可以參考下

#由於自己是野生程式設計師,在剛開始學習程式設計的時候沒有在意記憶體這些基礎知識,導致後來在提到「什麼什麼是存在堆疊中的,棧中只是存了一個引用」這樣的話時總是一臉懵逼。 。

後來漸漸的了解了一些記憶體的知識,這部分還是非常有必要了解的。

基本資料結構

堆疊

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

堆是基於雜湊演算法的資料結構。

佇列

佇列是一種先進先出(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为复合数据类型,他们的引用变量存储在栈中,指向于存储在堆中的实际对象。

由上图可知,我们无法直接操纵堆中的数据,也就是说我们无法直接操纵对象,但我们可以通过栈中对对象的引用来操作对象,就像我们通过遥控机操作电视机一样,区别在于这个电视机本身并没有控制按钮。

现在让我们来回答为什么引用值要放在堆中,而原始值要放在栈中的问题:

记住一句话:能量是守衡的,无非是时间换空间,空间换时间的问题

堆比栈大,栈比堆的运算速度快,对象是一个复杂的结构,并且可以自由扩展,如:数组可以无限扩充,对象可以自由添加属性。将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。相对于简单数据类型而言,简单数据类型就比较稳定,并且它只占据很小的内存。不将简单数据类型放在堆是因为通过引用到堆中查找实际对象是要花费时间的,而这个综合成本远大于直接从栈中取得实际值的成本。所以简单数据类型的值直接存放在栈中。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。更多相关教程请访问JavaScript视频教程

相关推荐:

php公益培训视频教程

JavaScript图文教程

JavaScript在线手册

以上是js基礎心法之資料類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:jb51.net。如有侵權,請聯絡admin@php.cn刪除