这几天看vue-router的源码 发现了Object.prototype.toString.call()这样的用法,当时觉得这就是转成字符串的用的,可是越看越以为不太对劲,赶忙查查资料,一查才知道没那么简单.vue
首先在Object.prototype.toString方法被调用时,会执行下面的操做步骤:vue-router
1. 获取this对象的[[Class]]属性的值.数组
2. 计算出三个字符串"[object ", 第一步的操做结果Result(1), 以及 "]"链接后的新字符串.this
3. 返回第二步的操做结果Result(2).spa
[[Class]]是一个内部属性,全部的对象(原生对象和宿主对象)都拥有该属性.在规范中,[[Class]]是这么定义的prototype
内部属性 | 描述 |
---|---|
[[Class]] | 一个字符串值,代表了该对象的类型. |
看这里重点: [[Class]] 代表了该对象的类型router
并且除了经过Object.prototype.toString方法以外,没有提供任何其余方式来让程序访问该属性的值. 看到这里我就想到了 Object.prototype.toString 是否是能够用来检测对象的类型,并且vue-router源码里面正好就是用来检测对象类型的.对象
等等 隐约记得 typeof 和 instanceof 也是用来检测类型的 后来查阅资料 blog
typeof 只能区分基本类型,即 “number”,”string”,”undefined”,”boolean”,”object” 五种。字符串
对于数组、对象来讲,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。
能够检测自定义类型 可是检测的必须是对象( Object ). 好比若是想检测 a是什么类型 要先检测他是不是Object 类型 而后才能用instanceof , 这就麻烦了.
而Object.prototype.toString就没有这么多限制.
[[Class]]属性的值能够是除了 "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"以外的的任何字符串
看下面的例子
下面是实战:
console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call('123')) //[object String] console.log(Object.prototype.toString.call(undefined)) //[object Undefined] console.log(Object.prototype.toString.call(true)) //[object Boolean] console.log(Object.prototype.toString.call({})) //[object Object] console.log(Object.prototype.toString.call([])) //[object Array] console.log(Object.prototype.toString.call(function(){})) //[object Function]
console.log(Object.prototype.toString.call(null)) //[object Null
什么类型均可以,完美.
最后加个 toString()的知识点 直接看演示:
若是不带括号 直接对 1 使用 toStirng()的时候 会把.当作小数点 而后报错 因此应该使用 1..toString();