爲什麼Object.toString.call([1,2,3])返回[object Array]?可以直接[].toString()返回[object Array]嗎?
難道真的像自己理解的那樣,是通過call將[1,2,3]作爲Object.toString的實參傳遞了進去嗎?不是。
直接Object.toString([1,2,3])不能實現同樣的功能嗎?不能。
而實際上也有Array.__proto__.toString()
這種形式,所以是可以直接調用arr.toString()的,這樣能檢測出嗎?不行。
那到底是什麼原因?
先來肝一個表格。
爲什麼會出現下面的情況?
Object.toString.call(Array)//"function Array() { [native code] }"
Object.prototype.toString.call(Array)//"[object Function]"
答案在這裏!
Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"
Object對象和它的原型鏈上各自有一個toString()方法,第一個返回的是一個函數,第二個返回的是值類型。
既然知道了不同,現在我們再來分析下Object.prototype.toString.call(Array)//"[object Function]"
。
Array對象本身返回一個構造函數,Array//ƒ Array() { [native code] },而Object.prototype.toString()返回的是//"[object Type]"的形式,通過call將Array的this上下文切換到Object,從而調用了Object.prototype.toString(),因此返回[object Function]
。
需要注意的是:Math.toString()直接返回"[object Math]"。
實際開發中,我們用到最多的可能是:Object.prototype.toString.call([1,2,3])//"[object Array]"這種。
總結:
- 一般情況下,js中對象的toString(),返回字符串,內容與函數聲明語法有關,例如[1,2,3].toString()//"1,2,3"
- 大多數都返回函數的完整源碼,Array.toString()//"function Array() { [native code] }"
- 內置函數往往返回一個類似"[native code]"的函數體,需要配合call方法,比如Object.prototype.toString.call([1,2,3])//"[object Array]"
那麼不可以直接Array.prototype.toString.call([1,3,4])嗎?
不行!
因爲Array,Function,Date雖然是基於Object進行創建的,但是他們繼承的是Object.toString(),而不是Object.prototype.toString()。
再加深一遍印象:
Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"
所以這就是必須用Object.prototype.toString()去檢測類型的原因。
至於Object.prototype.toString()內部是怎麼實現的,等到時機成熟再去深入。
參考:
作者:趁你還年輕233
鏈接:https://www.jianshu.com/p/e4237ebb1cf0
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。