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循環不生效。
破菲特!
誒,等等,還有$是怎么回事兒?
???
