在vue的源码中,vue/src/shared/util.js文件中存放的是一些方法。其中作者用了Object.prototype.toString这个方法来判断类型,但是并没有直接用,而是单独保存在一个变量:
const _toStr = Object.prototype.toString
那么为什么要这么做呢?
先说下判断类型。众所周知,typeof在判断对象时不能正确判断Null,并且不能识别出Array,但在判断基础类型时是没问题的。所以尤大也写了:
export function isPrimitive (value: any): boolean %checks { return ( typeof value === 'string' || typeof value === 'number' || // $flow-disable-line typeof value === 'symbol' || typeof value === 'boolean' )}
判断Object也做了区分,isObject和isPlainObject :
export function isObject (obj: mixed): boolean %checks { return obj !== null && typeof obj === 'object'}export function isPlainObject (obj: any): boolean { return _toString.call(obj) === '[object Object]'}
到了判断复杂类型的时候,一般我们用Object.prototype.toString
或者是instanceof。如果是前者的话会返回类似'[object Object]'的字符串。后者则会判断一个对象的原型链上是否存在一个构造函数。
两者还有一些不同。Object.prototype.toString.call(1)
和 Object.prototype.toString.call(Number(1))
时,返回的都是"[object Number]",
也就是说,它并不能区分原始类型和复杂类型。可见,Object.prototype.toString.call
并不像很多教程说的那样好用。
Object.prototype.toString.call(1)"[object Number]"Object.prototype.toString.call(Number(1))"[object Number]"
如果要使用,就需要像尤大一样,把原始类型单独拎出来判断,再去判断复杂类型,而走到这一步的时候尤大就写了上面说那行const _toStr。这是因为,toString实在是太容易被重写了。如果toString被其他人重写,将会对代码中涉及到的部分造成影响,所以就保存下来防止这种情况发生。
补充:Object.prototype.toString方法的原理
前言
我们在判断一个对象的内置类型时,我们一般可以使用以下方法:
var arr = [];console.log(Object.prototype.toString.call(arr)) //"[object Array]"
那么,这个方法的原理是什么呢?
ECMAScript 3
在toString方法被调用时,会执行下面的操作步骤:
1. 获取this对象的[[Class]]属性的值.
2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.
3. 返回第二步的操作结果Result(2).
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性.在规范中,[[Class]]是这么定义的
[[Class]] 一个字符串值,表明了该对象的类型.
新闻热点
疑难解答
图片精选