JavaScript 的數據類型及其檢測

1、JavaScript 有幾種類型的值?git

Javascript 有兩種數據類型,分別是基本數據類型和引用數據類型。其中基本數據類型包括 Undefined、Null、Boolean、Number、String、Symbol (ES6 新增,表示獨一無二的值),而引用數據類型統稱爲 Object 對象,主要包括對象、數組和函數。接下來咱們分別看下二者的特色。github

2、基本數據類型數組

一、值是不可變的瀏覽器

92814b3425f442f4bc5577812ec882b4.png

由此可得,基本數據類型的值是不可改變的
函數


二、存放在棧區性能


原始數據類型直接存儲在棧(stack)中的簡單數據段,佔據空間小、大小固定,屬於被頻繁使用數據,因此放入棧中存儲。測試


三、值的比較this

282bd8677da54e4db6ce5a436401bd7d.png

== : 只進行值的比較,會進行數據類型的轉換。prototype

=== : 不只進行值得比較,還要進行數據類型的比較。3d

3、引用數據類型

一、值是可變的

b2467a7d8d6c4b1c9ad3714eb31d0b01.png

上面代碼說明引用類型能夠擁有屬性和方法,而且是能夠動態改變的。


二、同時保存在棧內存和堆內存


引用數據類型存儲在堆(heap)中的對象,佔據空間大、大小不固定,若是存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址後從堆中得到實體。



三、比較是引用的比較


當從一個變量向另外一個變量賦引用類型的值時,一樣也會將存儲在變量中的對象的值複製一份放到爲新變量分配的空間中。

f8edac4836a04fbfaeb3605ef7ec08eb.png

上面咱們講到基本類型和引用類型存儲於內存的位置不一樣,引用類型存儲在堆中的對象,與此同時,在棧中存儲了指針,而這個指針指向正是堆中實體的起始位置。變量 a 初始化時,a 指針指向對象{age:20}的地址,a 賦值給 b 後,b 又指向該對象{age:20}的地址,這兩個變量指向了同一個對象。所以,改變其中任何一個變量,都會相互影響。



此時,若是取消某一個變量對於原對象的引用,不會影響到另外一個變量。

784d305aed964783ad25a7aa239e5f63.png

上面代碼中,a 和 b 指向同一個對象,而後 a 的值變爲 1,這時不會對 b 產生影響,b 仍是指向原來的那個對象。

4、檢驗數據類型

一、typeof


typeof 返回一個表示數據類型的字符串,返回結果包括:number、boolean、string、symbol、object、undefined、function 等 7 種數據類型,但不能判斷 null、array 等


5f2b9e4304f443c3b442533f2abc63f4.png

數組和對象返回的都是 object,這時就須要使用 instanceof 來判斷


二、instanceof


instanceof 是用來判斷 A 是否爲 B 的實例,表達式爲:A instanceof B,若是 A 是 B 的實例,則返回 true,不然返回 false。instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。

8b89e6c5498c4cf7920afb84c0f57981.png

關於數組的類型判斷,還能夠用 ES6 新增Array.isArray()

cb2d983a95374885aee9d6a7eb1567a3.png

instanceof 三大弊端:


對於基本數據類型來講,字面量方式建立出來的結果和實例方式建立的是有必定的區別的


3b106c40ce0a48b2a15305081d8924b7.png

從嚴格意義上來說,只有實例建立出來的結果纔是標準的對象數據類型值,也是標準的 Number 這個類的一個實例;對於字面量方式建立出來的結果是基本的數據類型值,不是嚴謹的實例,可是因爲 JS 的鬆散特色,致使了可使用 Number.prototype 上提供的方法。


只要在當前實例的原型鏈上,咱們用其檢測出來的結果都是 true。在類的原型繼承中,咱們最後檢測出來的結果未必準確。


00d0c642d1a64c639600f6311a9d874c.png

不能檢測 null 和 undefined


對於特殊的數據類型 null 和 undefined,他們的所屬類是 Null 和 Undefined,可是瀏覽器把這兩個類保護起來了,不容許咱們在外面訪問使用。



三、嚴格運算符===


只能用於判斷 null 和 undefined,由於這兩種類型的值都是惟一的。



2e4283c3ec95426780c3b1bc50004c21.png

undefined 還能夠用 typeof 來判斷

a95de06b55d74dbc8477c8a9c8fa0d9d.png

四、constructor


constructor 做用和 instanceof 很是類似。但 constructor 檢測 Object 與 instanceof 不同,還能夠處理基本數據類型的檢測。

e9ab1fd915114ba79839510e21f7f5af.png

constructor 兩大弊端:


null 和 undefined 是無效的對象,所以是不會有 constructor 存在的,這兩種類型的數據須要經過其餘方式來判斷。


函數的 constructor 是不穩定的,這個主要體如今把類的原型進行重寫,在重寫的過程當中頗有可能出現把以前的 constructor 給覆蓋了,這樣檢測出來的結果就是不許確的

5d09a61db8bc410582716ec7b4b3ee2d.png

五、Object.prototype.toString.call()


Object.prototype.toString.call() 最準確最經常使用的方式。首先獲取 Object 原型上的 toString 方法,讓方法執行,讓 toString 方法中的 this 指向第一個參數的值。


關於 toString 重要補充說明:


  • 本意是轉換爲字符串,可是某些 toString 方法不只僅是轉換爲字符串

  • 對於 Number、String,Boolean,Array,RegExp、Date、Function 原型上的 toString 方法都是把當前的數據類型轉換爲字符串的類型(它們的做用僅僅是用來轉換爲字符串的)

  • Object 上的 toString 並非用來轉換爲字符串的。


Object 上的 toString 它的做用是返回當前方法執行的主體(方法中的 this)所屬類的詳細信息即"[object Object]",其中第一個 object 表明當前實例是對象數據類型的(這個是固定死的),第二個 Object 表明的是 this 所屬的類是 Object。


0060ca211efc4c6abb4e750c0c8d03ca.png


做者:浪裏行舟

連接:https://github.com/ljianshu/Blog/issues/4

相關文章
相關標籤/搜索