Object.prototype.toString.call(obj) 與 obj.toString

判斷一個變量的類型

typeof

一般使用 typeof a; 這樣的方式也能夠去判斷一個變量的類型,但問題在於不嚴謹。好比:數組

typeof null;   // object
typeof [];     // object

但有時候,咱們須要的是更‘純粹’的對象,這個時候怎麼辦呢?prototype

Object.prototype.toString.call(obj)

使用如標題那樣的方式能夠更好的區分各類變量的類型: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呢 ?原型鏈

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方法有可能會被改寫。

相關文章
相關標籤/搜索