一般使用 typeof a; 這樣的方式也能夠去判斷一個變量的類型,但問題在於不嚴謹。好比:數組
typeof null; // object typeof []; // object
但有時候,咱們須要的是更‘純粹’的對象,這個時候怎麼辦呢?prototype
使用如標題那樣的方式能夠更好的區分各類變量的類型:code
console.log(Object.prototype.toString.call("jerry"));//[object String] console.log(Object.prototype.toString.call(12)); //[object Number] console.log(Object.prototype.toString.call(true)); //[object Boolean] console.log(Object.prototype.toString.call(undefined));//[object Undefined] console.log(Object.prototype.toString.call(null)); //[object Null] console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object] console.log(Object.prototype.toString.call(function(){})); //[object Function] console.log(Object.prototype.toString.call([])); //[object Array] console.log(Object.prototype.toString.call(new Date)); //[object Date] console.log(Object.prototype.toString.call(/\d/)); //[object RegExp]
美中不足的是,沒法區分出自定義對象:對象
function Person(){}; console.log(Object.prototype.toString.call(new Person)); //[object Object]
但還有 instanceof繼承
new Person() insatnceof Person; // true
爲何這樣能夠區分呢?
由於toStirng方法返回一個變量(包含對象)的字符串表示方式。那既然這樣,爲何不直接使用obj.toString呢 ?原型鏈
console.log("jerry".toString()); //jerry console.log((1).toString()); //1 console.log([1,2].toString()); //1,2 console.log(new Date().toString());//Wed Dec 21 2016 20:35:48 GMT+0800 (中國標準時間) console.log(function(){}.toString());//function (){} console.log(null.toString()); //error console.log(undefined.toString()); //error
一樣是檢測變量類型的方法,Object.prototype.toString.call(obj) 與 obj.toStirng 怎麼會結果不同呢?字符串
這是由於toString方法是Objectde 原型方法,而 Array, function等類型做爲Object的實例(Function是Object的子類,function又是Function的實例),都繼承並重寫了toString方法,不一樣的對象類型的對象調用toStirng方法時,其實調用的是重回寫以後的toString方法,而再也不去調用Object原型上的toString方法了。原型
咱們能夠驗證一下,將數組的toString方法刪除,看看會是什麼結果:io
var arr=[1,2,3]; console.log(Array.prototype.hasOwnProperty("toString")); //true console.log(arr.toString()); //1,2,3 delete Array.prototype.toString; //delete操做符能夠刪除實例屬性 console.log(Array.prototype.hasOwnProperty("toString")); //false console.log(arr.toString()); //"[object Array]"
刪除了Array的toString方法後,一樣再採用arr.toString()方法調用時,再也不有屏蔽Object原型方法的實例方法,所以沿着原型鏈,arr最後調用了Object的toString方法,返回了和Object.prototype.toString.call(arr)相同的結果。console
另外,不直接使用obj.toString方法的緣由,還有一個就是obj對象的toString方法有可能會被改寫。