1.typeof
語法:typeof 變量
在javascript中伟众,我們經(jīng)常用typeof 變量
方法來判斷一個變量的類型算灸,該方法返回值為 字符串蛤吓。
我們先看下面例子測試下
var a = 34,
b = 'adsfas',
c = true,
d = function () {
},
e = null,
f,
g = [34, 4, 3, 54],
h={},
i=Symbol(),
j=new d();
console.log(typeof (a)); //"number"
console.log(typeof (b)); //"string"
console.log(typeof (c)); //"boolean"
console.log(typeof (d)); //"function"
console.log(typeof (e)); //"object"
console.log(typeof (f)); //"undefined"
console.log(typeof (g)); //"object"
console.log(typeof (h)); //"object"
console.log(typeof (i)); //"symbol"
console.log(typeof (j)); //"object"
我們會發(fā)現(xiàn):
- typeof在判斷
null充活、array硼砰、object以及函數(shù)實例(new + 函數(shù))
時且蓬,得到的都是"object"
。所以當我們在判斷這些數(shù)據(jù)類型時题翰,typeof
并不能確定的告訴我們具體是哪種數(shù)據(jù)類型恶阴。由此引出instanceof
。
2.instanceof
語法:object instanceof constructor
object:要檢測的對象(一般為對象豹障,如果為基本類型冯事,雖然返回false,不過沒什么意義)
constructor:構(gòu)造函數(shù)
注:constructor必須是個構(gòu)造函數(shù)
- 如果是基本類型(如[] instanceof 1)會報錯 Uncaught TypeError: Right-hand side of 'instanceof' is not an object;即右側(cè)不是個對象
- 如果是引用類型(如 [] instanceod [])會報錯: Uncaught TypeError: Right-hand side of 'instanceof' is not callable;即右側(cè)不可調(diào)用
在javascript中血公,instanceof 運算符用來檢測 constructor.prototype 是否存在于參數(shù) object 的原型鏈上昵仅,該方法返回值為布爾值(true/false)。什么意思坞笙?從字面意思上看岩饼,instanceof
跟原型鏈有關(guān),所有在解釋這句話之前薛夜,需要有js原型的知識籍茧,不懂的可以戳這js原型、原型鏈梯澜。
舉個例子:
console.log([] instanceof Array) // true
console.log([] instanceof Object) // true
console.log([] instanceof Function) // false
console.log({} instanceof Array) // false
console.log({} instanceof Object) // true
console.log({} instanceof Function) // false
上面例子寞冯,運行結(jié)果各不相同。我們來分別解釋下:
-
[] instanceof Array===true
晚伙,根據(jù)定義解釋吮龄,即判斷Array的原型是否在[]的原型鏈上,很明顯[].__proto__===Array.prototype
,所以為true -
[] instanceof Object===true
咆疗,根據(jù)定義解釋漓帚,即判斷Object的原型是否在[]的原型鏈上,因為[].__proto__===Array.prototype
午磁,找不到會繼續(xù)往原型鏈找尝抖,所以應(yīng)該是找到[].__proto__.__proto__
, 也就是Array.prototype.__proto__
即Object.prototype
,所以為true -
[] instanceof Function===false
,根據(jù)定義解釋迅皇,即判斷Function的原型是否在[]的原型鏈上,和上面第二點一樣昧辽,一直沿著原型鏈找,找不到繼續(xù)找登颓,當?shù)?code>Object.prototype還是找不到搅荞,繼續(xù)找,直到為null,因為Object.prototype.__proto__===null
咕痛,所以為false
同理{} instanceof Object===true
因為{}.__proto__===Object.prototype
,其他兩個就不解釋了痢甘,和上面一樣,也是沿著原型鏈找暇检。我們可以用javascript模擬instanceOf
3.null和typeof产阱、instanceof的關(guān)系
直接看例子:
console.log(null instanceof Object); //false
console.log(typeof null); //'object'
console.log(null instanceof null); //報錯 Uncaught TypeError: Right-hand side of 'instanceof' is not an object
我們了解原型鏈的都知道,原型鏈的頂端就是null块仆。所以 null instanceof Object===false
沒什么問題。但是typeof null
結(jié)果為什么是'object'王暗,讓人以為null instanceof Object===true
悔据。實際typeof null==='object'
是一個歷史遺留下來的bug,本質(zhì)上null和object不是一個數(shù)據(jù)類型俗壹,null值并不是以O(shè)bject為原型創(chuàng)建出來的科汗,所以null instanceof Object===false
在 javascript 的最初版本中,使用的 32 位系統(tǒng)绷雏,為了性能考慮使用低位存儲了變量的類型信息:
- 000:對象
- 1:整數(shù)
- 010:浮點數(shù)
- 100:字符串
- 110:布爾
有 2 個值比較特殊:
- undefined:用 -(?2^30)表示头滔。
- null:對應(yīng)機器碼的 NULL 指針,一般是全零
所以涎显,typeof 在判斷類型時候坤检,實際是根據(jù)上面的機器碼存儲信息來判斷的,所以 null 就出現(xiàn)問題了期吓,由于 null 的所有機器碼均為0早歇,因此直接被當做了對象來看待,實際本質(zhì)上null(實際上是基本類型)和object(引用類型)壓根不是同一個數(shù)據(jù)類型讨勤,null在javascript中表示尚未創(chuàng)建的對象(空對象)箭跳。所以:
typeof null === 'object';
null instanceof Object === false
因為null是原型鏈的頂端,所以其沒有原型對象潭千,所以null instanceof null
會直接報錯谱姓。
4.null和{}
{}并不是一個完全空的對象,因為他的原型鏈上還有Object呢刨晴,而null就是完全空的對象屉来,啥也沒有,原型鏈也沒有割捅。所以奶躯,在js中,初始化一個空對象應(yīng)該用null亿驾,{}是初始化對象
5.使用javascript模擬instanceof
function instanceof(object,constructor){
if(typeof object!='object'||object===null){
return false
}
if(object===constructor.prototype){
return true
}else{
return instanceof(object.__proto__,constructor)
}
}
上面的代碼應(yīng)該很容易看懂嘹黔,我就不解釋了。