一般使用 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方法有可能会被改写。