首頁  >  文章  >  後端開發  >  JavaScript基礎心法 資料型別

JavaScript基礎心法 資料型別

php中世界最好的语言
php中世界最好的语言原創
2018-03-06 13:27:561188瀏覽

JavaScript一種直譯式腳本語言,是一種動態類型、弱型別、基於原型的語言,內建支援類型。所以JavaScript是一個很基礎的知識點,這篇主要是介紹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事件处理机制解析

javascript模块加载器详细说明

JavaScript关于图片处理与合成的方法详解

 

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn