1. 程式人生 > >Vue原始碼中為什麼要const _toStr = Object.prototype.toString?

Vue原始碼中為什麼要const _toStr = Object.prototype.toString?

在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被其他人重寫,將會對程式碼中涉及到的部分造成影響,所以就儲存下來防止這種情況發生。