談到JS的類型判斷陋守,首先我們先了解JS當(dāng)中的數(shù)據(jù)類型內(nèi)容废登。
JS數(shù)據(jù)基本類型和引用類型
基本類型:undefined淹魄、null、string堡距、number甲锡、boolean、symbol(ES6)
普通基本類型:undefined羽戒、null缤沦、symbol(ES6)
特殊基本包裝類型:String、Number易稠、Boolean
引用類型:Object缸废、Array、RegExp驶社、Date企量、Function
區(qū)別:引用類型值可添加屬性和方法,而基本類型值則不可以亡电。
基本類型
基本類型的變量是存放在棧內(nèi)存(Stack)里的
基本數(shù)據(jù)類型的值是按值訪問的ya
基本類型的值是不可變的
基本類型的比較是它們的值的比較
引用類型
引用類型的值是保存在堆內(nèi)存(Heap)中的對象(Object)
引用類型的值是按引用訪問的
引用類型的值是可變的
引用類型的直接比較是引用地址的比較
JS數(shù)據(jù)類型
NaN是數(shù)字類型
判斷引用類型:Object.prototype.toString.call(value)
- 原理
Object.prototype.toString關(guān)鍵代碼中届巩,最終返回的對象是'[object ' + classof(this) + ']'
字符串。
可以理解為:說該方法會(huì)返回當(dāng)前this
對象的對應(yīng)的類型class
字符串
'use strict';
// 19.1.3.6 Object.prototype.toString()
require('./_redefine')(Object.prototype, 'toString', function toString() {
return '[object ' + classof(this) + ']';
}, true);
classof(this)
偽代碼邏輯:
this === undefined;return 'Undefined'
this === null;return 'Null'
O = ToObject(this value)
把當(dāng)前對象轉(zhuǎn)換成Object
因?yàn)閖s中Object key值只允許string或者Symbol類型
IsArray(O)判斷是否是數(shù)組對象
IsArray判斷邏輯:
Type(O)判斷是否是Object份乒,不是直接return false;
O是否為Array exotic object:
如果O的[[DefineOwnProperty]]和Array的方法一樣:
大概邏輯是:
內(nèi)置定義的length屬性恕汇,length屬性不可以人為修改
O內(nèi)置定義的所有key值是可以類型轉(zhuǎn)換成數(shù)字的字符串,
并且最終數(shù)字范圍必須在0~2^32-1次方以內(nèi)或辖,
length的取值要大于0所有的key對應(yīng)的array index
....
就認(rèn)為這個(gè)是個(gè)Array對象,return 'Array';
...
注:不同版本的js規(guī)范中實(shí)現(xiàn)邏輯可能略有不同
ECMA#sec-object.prototype.tostring
- 應(yīng)用:
Array.isArray = function(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
value instanceof Type == true/false
- instanceof實(shí)現(xiàn)原理:看實(shí)例的___proto____指向的原型鏈上瘾英,有沒有跟右側(cè)類型的prototype指向同一個(gè)對象的
function new_instance_of(leftVaule, rightVaule) {
let rightProto = rightVaule.prototype; // 取右表達(dá)式的 prototype 值
leftVaule = leftVaule.__proto__; // 取左表達(dá)式的__proto__值
while (true) {
if (leftVaule === null) {
return false;
}
if (leftVaule === rightProto) {
return true;
}
leftVaule = leftVaule.__proto__
}
}
- 局限:假設(shè)只有一個(gè)單一的全局環(huán)境。如果網(wǎng)頁當(dāng)中包含多個(gè)框架颂暇,存在兩個(gè)以上不同的全局執(zhí)行環(huán)境缺谴,因?yàn)榇嬖趦蓚€(gè)以上不同版本的Array構(gòu)造函數(shù)。如果從一個(gè) 框架向另一個(gè)框架傳入一個(gè)數(shù)組蟀架,傳入的數(shù)組與在第二個(gè)框架中原生創(chuàng)建的數(shù)組構(gòu)造函數(shù)不同瓣赂。《Javascript高級(jí)教程》
typeof value
- 取值:'undefined'/'boolean'/'string'/'number'/'object'/'function'/'symbol'
- typeof不能判斷object具體是哪種類型片拍,比如:Array之類的
- typeof null 為'object'煌集,其實(shí)是錯(cuò)誤的,因?yàn)閚ull不是object類型捌省。
判斷原理:根據(jù)變量的機(jī)器碼低位1-3位存儲(chǔ)其類型信息苫纤。
000:對象
010:浮點(diǎn)數(shù)
100:字符串
110:布爾
1:整數(shù)
因?yàn)閚ull所有機(jī)器碼都是0,所以typeof會(huì)把null判斷為對象
typeof 原理適合的使用場景:判斷除了object之外的基本類型,避免判斷null卷拘。