一、定義
1. 什麼是資料型別?
資料型別,就是將資料按照某一規則進行區別時所定義的分類標籤。比如說,同樣都是漢字組成的詞語,要分動詞、名詞、介詞等。
2. 為什麼會有資料型別?它出現的意義是什麼?
對資料分類,主要有兩個原因:
第一,為了限制不同種類資料的操作。比如說當你宣告一個變數是一個數字,那麼,就只能對這個變數進行數字能進行的操作,這在編譯程式碼及排查錯誤時尤為重要。
第二,由於所有的資料都要儲存在計算機中,不同型別資料的儲存位置及所需要的記憶體大小也不一樣,而對資料分類後,程式設計時需要用大資料的時候才需要申請大記憶體,這樣可以充分利用記憶體。
例如大胖子必須睡雙人床,就給他雙人床,瘦的人單人床就夠了。
二、JavaScript 中的資料型別
1. 為什麼稱 JavaScript 為弱型別語言?
JavaScript 中變數是沒有型別的,只有值才有。變數可以隨時持有任何型別的值。
舉個例子:
// js
let a = 4;
a = '4';
a = false;
複製程式碼
從上面的例子中可以看到,我們宣告 a
是一個數字,但是我們在之後將 a
的值又改成了字串和布林值(後面會講這些型別)。可以看到,變數 a
的型別是可以隨意轉變的,這在強型別語言裡是不允許的。
因此,判斷一門語言是強型別還是弱型別,就看這門語言中一個變數是否可以賦不同資料型別的值。
2. JavaScript 有哪些資料型別?
在 JavaScript 中,共有七種資料型別,其中,六種是基本/原始型別,一種是物件/複合/引用型別。
基本型別:
- 字串(String):表示一個字串,如“find”。
- 數字(Number):表示一個數字,如 45 。
- 布林(Boolean):布林值,包括 false 和 true 。
- 未定義(undefined):只有一個值,undefined , 表示未給變數賦值。
- 空值(null):只有一個值, null , 表示空值得關鍵字。
- Symbol(es6新增):表示一個唯一且不可改變的值。
引用型別:
- 物件(object): 各種值組成的集合。
其中,物件型別還有一些子型別,如陣列,函式,JavaScript 的內建函式等。
3. 基本資料型別和複合資料型別有什麼區別?
主要有兩點:
-
基本型別的資料是不可再拆分的。 這也就是為什麼稱他為基本型別,就像組成單詞的 26 個英文字母、組成數字的 0 -9;而複合型別的資料,是由基本型別組成。比如一個單詞,可以由數個字母組成,一個句子,可以由數字、字母及標點複合組成。
-
它們在計算機中的儲存方式不同。計算機儲存資料時為了記憶體及執行速度考慮,往往會對儲存做優化,有的會將值本身儲存在棧記憶體中,也有可能會在棧記憶體中儲存一個值的引用,而把值本身存在堆記憶體中。對於不同的語言,實現起來或許會有不一致,但思想都是如此。
4. js 中值型別和引用型別的儲存方式是怎樣的?
對於 js 來講,是沒有棧記憶體的概念的,但是 js 在編譯執行程式碼時,會首先進入一個執行上下文,在執行上下文的建立階段,會開闢一片區域,用來儲存變數和它們的值,這個區域就叫做變數物件。
大概長這個樣子:
如上圖所示,對於基本型別的變數,他們的變數名和值都會儲存在這個變數物件中,而對於 d ,這個引用型別的值,則只是將這個變數的名字和地址存在變數物件中,變數的值是儲存在堆記憶體空間的。
關於執行上下文,後面會有文章專門講,暫時先不做深入講解。
5. 如何判斷一個資料的資料型別?
- typeof 方法
對於一個變數,使用 typeof
方法會返回一個唯一的資料型別字串。但這個方法並不怎麼靠譜。
值 | 型別 | typeof 值 |
---|---|---|
23 | number | "number" |
"abc" | string | "string" |
false | boolean | "boolean" |
undefined | undefined | "undefined" |
Symbol() | symbol | "symbol" |
{} | object | "object" |
null | null | "object" |
function(){} | object | "funciton" |
從上表中我們看到,有兩處地方和我們預期不一致。
-
typeof null
返回的是"object"
而不是"null"
。這是 js 語言設計時的一個 bug, 並且在未來也不會更改。想要正確判斷 null 可以加一個條件:
function typeOf(a) { if(!a && typeof a === "object") return "null"; return typeof a; } typeOf({}); // "object" typeOf(null); // "null" 複製程式碼
-
typeof function(){} === "function"
, 這是因為function
作為 js 的一等公民,是可以呼叫的物件,設計者認為有必要將它和普通物件區別開來。
- Object.prototype.toString.call() 方法
除了 typeof
方法外,呼叫 Object.prototype.toString.call()
方法 也可以返回一個包含資料型別的字串,並且更為準確。
值 | 型別 | Object.prototype.toString.call(值) |
---|---|---|
23 | number | '[object Number]' |
"abc" | string | '[object String]' |
false | boolean | '[object Boolean]' |
undefined | undefined | '[object Undefined]' |
Symbol() | symbol | '[object Symbol]' |
{} | object | '[object Object]' |
null | null | '[object Null]' |
function(){} | object | '[object Function]' |
[] | object | '[object Array]' |
從上面們可以看出,這方法對於型別的檢測更加精確。
因此,我們可以寫一個函式,用來精確檢測型別。
function getClass (a) {
const str = Object.prototype.toString.call(a)
return /^\[object (.*)\]$/.exec(str)[1]
}
getClass(null) // "Null";
...
複製程式碼
原文地址: 落明的 blog