作者:nicole_zhang18970
連接:https://juejin.im/post/6844903613584654344
來源:掘金
一般被用於判斷一個變量的類型,可判斷七種類型
number
,
string,
object,
boolean,
function,
undefined,
symbol
但有一個很麻煩的事情,只能知道那個變量是object不能知道更精確的類型
let s = new String('abc');
typeof s === 'object' // true
// 還必須靠instanceof
s instanceof String // true
而且還有一個老梗,就是null也會顯示object (上古bug)
typeof null // object
所以typeof通常只被用來檢查基本類型
附註: 有一個不錯的方法
可以利用這個做出更精銳的判斷
Object.prototype.toString.call(5) // "[object Number]"
Object.prototype.toString.call('foo') // "[object String]"
Object.prototype.toString.call({foo:'bar'}) // "[object Object]"
Object.prototype.toString.call(['foo','a']) // "[object Array]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(() => {}) // "[object Function]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
會顯示 typeof null 為 object 這個錯誤源自於 JavaScript 第一個版本。
於此版本中,JavaScript的值以32位元存儲,其中包括了一個小型單位標籤(1~3位),此類型標籤存在32位元的低位,如以下五個。
- 000:對象
- 010:浮點數
- 100:字符串
- 110:布爾
- 1:整數
那我們也就知道為啥null會跑出object了,因為null的所有機器碼全部都是0。
之後null的typeof為object從此被納入ECMA規格中,而所有現代引擎皆按照此規格沿用至今(所以引擎內部實現原理不一定還是為此)。
在講這個之前請務必先看以下文章,因為要先建立原型鍊的概念,講解也會用該文的概念去解釋
主要的作用是判斷一個實例是否屬於某種類型 (也可以是父類型或者祖先類型)
// 1.
function Person() {
...
}
let nicole = new Person()
nicole instanceof Person // true
// 2.
function Person () {
...
}
function Programmer () {
...
}
Programmer.prototype = new Person()
let nicole = new Programmer()
nicole instanceof person // true
nicole instanceof Programmer // true
其實就是先找右邊的prototype( 因為機器的prototype會等於實例的__ proto __ )
然後跟左邊的p比較如果不相等就再往上找直到取到null 並 return false
代碼:
// 不難就上面提到的概念看一下應該就會懂
function new_instance_of(leftVaule, rightVaule) {
let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
while (true) {
if (leftVaule === null) {
return false;
}
if (leftVaule === rightProto) {
return true;
}
leftVaule = leftVaule.__proto__
}
}
既然知道到底再比較甚麼就好辦啦,直接看例子吧
附註:以下需先閱讀D03內容,否則會看不懂
答案:
true
解析:
右邊: Object 的 prototype 是 NO1
左邊: Object的p往上找會有NO1
示意圖:
true
解析:
右邊: Function的prototype是NO2
左邊: Function的p往上就是NO2
示意圖:
答案:
true
解析:
右邊: Object的prototype指向NO1
左邊: Function的p往上找會有NO1
示意圖(因為右邊只需要prototype是啥,所以我在這裡沒畫Object的proto):
答案:
false
解析:
右邊: Foo.prototype 指向某一個prototype
左邊: 但Foo的p往上找找不到prototype
示意圖:
附註:
因為右邊僅需要找到prototype所以我沒畫Foo.prototype.__ proto __指向誰(NO1),從這張圖可以發現從Foo往上找會直接找到根本找不到 Foo.prototype,因此會返回 false
答案:
true
解析:
右邊: Object.prototype 指向NO1
左邊: Foo的p往上找找的到NO1
示意圖:
答案:
true
解析:
右邊: Function.prototype 指向NO2
左邊: 但Foo的p往上找的到NO2
示意圖:
第一篇文章可能很有問題。古往今來的Javascript引擎何其多,而且有許多開放原始碼,最好找的到類型是這樣實做的舉出來做範例...而且JIT並不一定直接把Javascript翻成機器碼,可能是中間表示式,即使翻成機器碼以後也還可能因為最佳化而改變,中間的鴻溝很大。
您好,想請問第一篇文章是指D03那篇嗎?
https://juejin.im/post/6844903613584654344 講typeof這篇,尤其是「原理」
以下為MDN內容:
可以看到後面有一個參考來源
該來源連結為以下:
https://2ality.com/2013/10/typeof-null.html
可以閱讀一下,該篇文章原理來源翻譯自此。
我看過,你要讀懂原作者的意思。他的解釋是說這是第一版的JavaScript實做的bug,然後進入了ECMA-262,變成規格了。現代的Javascript語言會依照規格實做讓他表現起來是這樣,但這已經不是底層的原理。
了解。大至修改了一下,感謝您