1. 基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型
JavaScript中的變量是沒(méi)有類型的,只有值才有,變量可以隨時(shí)持有任何類型的值谢揪。JavaScript中值的類型分為基礎(chǔ)數(shù)據(jù)類型和引用數(shù)據(jù)類型。JavaScript中有5種基礎(chǔ)數(shù)據(jù)類型,分別是:
- Null(空值)
- Undefined(未定義:已聲明谢澈,未賦值)
- Boolean(布爾值)
- Number(數(shù)字)
- String(字符串)
ES6中新增了Symbol數(shù)據(jù)類型,Symbol是類字符串形式的基礎(chǔ)數(shù)據(jù)類型御板,暫不考慮锥忿。基礎(chǔ)數(shù)據(jù)類型都是按值訪問(wèn)怠肋,因?yàn)槲覀兛梢灾苯硬僮鞅4嬖谧兞恐械膶?shí)際的值敬鬓。JavaScript還有一種復(fù)雜數(shù)據(jù)類型:Object(對(duì)象類型)。引用數(shù)據(jù)類型就是由多個(gè)值組成的對(duì)象,所有引用類型的值都是Object的實(shí)例钉答。包括:
- Object(對(duì)象)
- Array(數(shù)組)
- Date(日期)
- ReqExp(正則表達(dá)式)
- Function(函數(shù))
- 基本包裝類型(3個(gè)特殊的引用類型:Boolean础芍、Number和String,為其對(duì)應(yīng)的基礎(chǔ)數(shù)據(jù)類型提供方法)
引用數(shù)據(jù)類型的值是保存在堆內(nèi)存中的對(duì)象数尿。JavaScript不允許直接訪問(wèn)堆內(nèi)存中的位置,因此我們不能直接操作對(duì)象的堆內(nèi)存空間右蹦。在操作對(duì)象時(shí)刽辙,實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。因此甲献,引用類型的值都是按引用訪問(wèn)的宰缤。這里的引用,我們可以理解為保存在變量對(duì)象中的一個(gè)地址晃洒,該地址與堆內(nèi)存的實(shí)際值相關(guān)聯(lián)慨灭。
2. 類型檢測(cè)
2.1 typeof
操作符
typeof
是一個(gè)操作符而不是函數(shù)(因此其操作數(shù)可以加括號(hào)也可以不加括號(hào)),用于檢測(cè)給定變量或字面量的數(shù)據(jù)類型球及,其返回值為代表類型的字符串氧骤,可能值為:
- "undefined" —— 這個(gè)值已聲明但未賦值
- "boolean" —— 這個(gè)值是布爾值,為true或false
- "string" —— 這個(gè)值是字符串
- "number" —— 這個(gè)值是數(shù)字
- "object" —— 這個(gè)值是對(duì)象(包括對(duì)象吃引、數(shù)組筹陵、日期和正則表達(dá)式)或null
- "function" —— 這個(gè)值是函數(shù)
typeof
操作符使用時(shí)有兩點(diǎn)值得注意:
(1) typeof null
的結(jié)果為 "object"。原理是這樣的镊尺,不同的對(duì)象在底層都表示為二進(jìn)制朦佩,在 JavaScript 中二進(jìn)制前三位都為 0 (數(shù)值的標(biāo)志位:1~3個(gè)字節(jié))的話會(huì)被判斷為 object 類型语稠, null 的二進(jìn)制表示是全 0,自然前三位也是 0弄砍,所以執(zhí)行 typeof 時(shí)會(huì)返回“ object ”仙畦。這個(gè)bug是第一版Javascript留下來(lái)的。在這個(gè)版本音婶,數(shù)值是以32字節(jié)存儲(chǔ)的慨畸,由標(biāo)志位(1~3個(gè)字節(jié))和數(shù)值組成型奥。
(2) 如下代碼:
var a;
typeof a; // "undefined"
typeof b; // "undefined"
a; // undefined
b; // ReferenceError: b is not defined
b未聲明但是使用 typeof 操作符檢測(cè)b未報(bào)引用錯(cuò)誤,而是返回undefined字符串碉京,說(shuō)明 typeof 有一個(gè)特殊的安全防范機(jī)制厢汹,實(shí)際工作中可以加以利用。因此在工作中承持妫可以看到類似如下的的代碼:
if (typeof DEBUG !== "undefined") {
console.log("Debugging is starting")
}
而不是這樣的代碼:
if (DEBUG) {
console.log("Debugging is starting")
}
因?yàn)镈EBUG變量一般只在debug.js文件中才有烫葬,而該文件只在開(kāi)發(fā)和測(cè)試時(shí)才被加載到瀏覽器中,在生產(chǎn)環(huán)境中不予加載凡蜻,若使用第二種寫法搭综,則在生產(chǎn)環(huán)境中會(huì)報(bào)引用錯(cuò)誤。
2.2 toString
- typeof 操作符除了函數(shù)之外划栓,不能獲取其他對(duì)象的信息兑巾,使用 toString 則不管是object類型還是primitive類型,都能得到你想要的結(jié)果:
console.log(toString.call(123));
console.log(toString.call(true));
console.log(toString.call(Symbol('foo')));
console.log(toString.call('some string'));
console.log(toString.call([1, 2]));
console.log(toString.call(new Date()));
console.log(toString.call({
a: 'a'
}));
// output
[object Number]
[object Boolean]
[object Symbol]
[object String]
[object Array]
[object Date]
[object Object]
2.3 instanceof
操作符
-
toString
只可以用于判斷內(nèi)置的數(shù)據(jù)類型忠荞,對(duì)于我們自己構(gòu)造的對(duì)象蒋歌,它還是不能給出我們想要的結(jié)果,這時(shí)需要使用instanceof
委煤。 - 對(duì)于使用構(gòu)造函數(shù)創(chuàng)建的對(duì)象堂油,我們通常使用
instanceof
來(lái)判斷某一實(shí)例是否屬于某種類型,例如:a instanceof Person
碧绞,其內(nèi)部原理實(shí)際上是判斷Person.prototype
是否在a實(shí)例的原型鏈中府框。 - 檢測(cè)基礎(chǔ)數(shù)據(jù)類型用typeof操作符,檢測(cè)引用數(shù)據(jù)類型則用
instanceof
操作符讥邻,其語(yǔ)法如下所示:
result = variable instanceof constructor
迫靖,如果變量是給定引用數(shù)據(jù)類型(根據(jù)它的原型鏈來(lái)識(shí)別)的實(shí)例,那么instanceof
操作符就會(huì)返回true兴使。如果使用instanceof操作符檢測(cè)基本數(shù)據(jù)類型的值袜香,則始終會(huì)返回false,因?yàn)榛绢愋筒皇菍?duì)象鲫惶。
3. Undefined類型和Null類型對(duì)比
Undefined類型和Null類型都是一值類型,即只有一個(gè)值的數(shù)據(jù)類型实抡。Undefined類型的值為特殊的undefined欠母,Null類型的值為特殊的null。
3.1 Undefined類型
undefined表示"缺少值"吆寨,就是此處應(yīng)該有一個(gè)值赏淌,但是還沒(méi)有定義。典型用法是:
- 變量被聲明了啄清,但沒(méi)有賦值時(shí)六水,就等于undefined俺孙。
- 調(diào)用函數(shù)時(shí),應(yīng)該提供的參數(shù)沒(méi)有提供掷贾,該參數(shù)等于undefined睛榄。
- 對(duì)象沒(méi)有賦值的屬性,該屬性的值為undefined想帅。
- 函數(shù)沒(méi)有返回值時(shí)场靴,默認(rèn)返回undefined。
3.2 Null類型
null表示"沒(méi)有對(duì)象"港准,即該處不應(yīng)該有值旨剥。典型用法是:
- 作為函數(shù)的參數(shù),表示該函數(shù)的參數(shù)不是對(duì)象浅缸。
- 作為對(duì)象原型鏈的終點(diǎn)轨帜。
3.3 注意
(1) undefined值是派生自null值的,因此位于null和undefined之間的相等操作符(==)總返回true衩椒。
null == undefined; //true
null === undefined; //false
(2) null是一個(gè)表示"無(wú)"的對(duì)象蚌父,轉(zhuǎn)為數(shù)值時(shí)為0;undefined是一個(gè)表示"無(wú)"的原始值烟具,轉(zhuǎn)為數(shù)值時(shí)為NaN梢什。
Number(null); //0
Number(undefined); //NaN