`Vue`中為什么訪問不了以`$`和`_`開頭的屬性?


Vue中為什么訪問不了以$_開頭的屬性?

背景:航班管家H5使用了Vue進行新版開發,預訂流程邏輯copy參考了野鵝國際機票小程序,小程序中使用__開頭的屬性作為私有屬性。

如題,在data中定義的以_開頭的屬性就不 work 了。我很想問一句:WTF?

官方解答

以 _ 或 $ 開頭的屬性 不會 被 Vue 實例代理,因為它們可能和 Vue 內置的屬性、API 方法沖突。—— data

emm,奈斯!本次分享可以結束了。

然鵝,你想不想知道Vue內部是如何屏蔽掉此類屬性的呢?往下看↓

在繼續之前,我們有必要先了解下Proxy是個什么東西。

Proxy

Proxy譯為'代理器',在目標對象之前架設一層“攔截”,外界對該對象的訪問,都必須先通過這層攔截。

舉個栗子:假設你要和韓梅梅相親,但妹子豈是你想見就見的?就需要一個中間人——媒婆作為韓梅梅的代理人和你通信。這里的媒婆所謂的代理器了。

雖然這個概念早已有之,但直到ES6才出現在javascript中。Proxy提供了一種機制,可以對外界的訪問進行過濾和改寫:

var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

proxy.time // 35
proxy.name // 35

阮老師的ECMAScript 6 入門——proxy講的很詳細。

Vue 實現

當執行new Vue()時,函數內部會執行_init()方法,其中有這一段:

// src/core/instance/init.js

Vue.prototype._init = function (options?: Object) {
  ...

  if (process.env.NODE_ENV !== 'production') {
    initProxy(vm)
  } else {
    vm._renderProxy = vm
  }

  ...
}

initProxy來自src/core/instance/proxy.js

initProxy = function initProxy (vm) {
  vm._renderProxy = new Proxy(vm, {
    has (target, key) {
      const has = key in target
      const isAllowed = key.charAt(0) === '_'
      return has || !isAllowed
    }
  })
}

proxy.js中,has方法用於攔截hasProperty操作,用來判斷對象是否有某個屬性或方法。

結論

當在Vue中訪問對象的屬性時,initProxy函數會將那些以_開頭的屬性給過濾掉。

另,has攔截的是hasProperty操作,而不是hasOwnProperty

再另,雖然for...in循環也用到了in運算符,但是has攔截對for...in循環不生效。

破菲特!

誒,等等,還有$是怎么回事兒?

???


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM