Vue源码中为何要const _toStr = Object.prototype.toString?

在vue的源码中,vue/src/shared/util.js文件中存放的是一些方法。其中做者用了Object.prototype.toString这个方法来判断类型,可是并无直接用,而是单独保存在一个变量:vue

const _toStr = Object.prototype.toString
复制代码

那么为何要这么作呢?git

先说下判断类型。众所周知,typeof在判断对象时不能正确判断Null,而且不能识别出Array,但在判断基础类型时是没问题的。因此尤大也写了:github

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 :bash

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并不像不少教程说的那样好用。ui

Object.prototype.toString.call(1)
"[object Number]"

Object.prototype.toString.call(new Number(1))
"[object Number]"
复制代码

若是要使用,就须要像尤大同样,把原始类型单独拎出来判断,再去判断复杂类型,而走到这一步的时候尤大就写了上面说那行const _toStr。这是由于,toString实在是太容易被重写了。若是toString被其余人重写,将会对代码中涉及到的部分形成影响,因此就保存下来防止这种状况发生。spa