在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