博客 / 詳情

返回

Object.toString.call()、Object.prototype.toString.call()?傻傻分不清楚

平常我們判斷某個變量類型的時候,會這樣寫:

var foo;
Object.prototype.toString.call(foo);
// "[object Undefined]"

今天手誤,錯寫成了這樣:

var foo;
Object.toString.call(foo);

// VM40:1 Uncaught TypeError: 
// Function.prototype.toString requires that 'this' be a Function
//  at toString (<anonymous>)
//  at toString (<anonymous>:1:765)
//  at <anonymous>:2:17

結果報錯了,發生了什麼?
提示我傳入的 foo 應該是個 Function,但很明顯 foo 是個 undefined。改一下試試看:

var foo = function(){};
Object.toString.call(foo);
// "function(){}"

這讓我疑惑了,function(){} 這個結果應該是對一個函數調用 toString 的結果,於是:

var foo = function(){};
foo.toString();
// "function(){}"

果然,那是不是説明 Object.toStringFunction.toString 可能存在着某種關係,難道他們是一樣的:

Object.toString == Function.toString
// true

原本以為 Object.toString == Object.prototype.toString 應該是 true,看來,有必要複習下 prototype 的相關知識點了。

那麼,為什麼 Object.toString == Function.toString 結果是 true 呢?我們先看下 ObjectFunction 分別是什麼類型:

使用 Object.prototype.toString.call() 方式

Object.prototype.toString.call(Object)
// "[object Function]"
Object.prototype.toString.call(Function)
// "[object Function]"

也就是説, ObjectFunction 都是函數,調用其 toString 應該都是調用的 Function.prototype.toString,所以二者本質是一樣的。

再來驗證下

Object instanceof Function
// true
Function instanceof Function
// true
Object.constructor === Function
// true
Function.constructor === Function
// true

二者都是 Function 的實例,調用其 toString 方法,其本質都是調用構造函數 Function.prototype.toString

回到最開始的問題,Object.toString.call()Object.prototype.toString.call()有什麼區別?

區別大了,前者調用的是 Object 構造函數 Function 的原型對象的 toString 方法,後者才真正調用的 Object 原型對象的 toString 方法,所以才導致了文章開頭的異常。

文章最後,提醒自己,寫代碼要細心,少個字母大相徑庭,做個嚴謹的工程師

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.