zoukankan      html  css  js  c++  java
  • `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循环不生效。

    破菲特!

    诶,等等,还有$是怎么回事儿?

    ???

  • 相关阅读:
    C# 局部函数与事件
    PHP curl_multi_strerror函数
    PHP curl_multi_setopt函数
    PHP curl_multi_select函数
    PHP curl_multi_remove_handle函数
    PHP curl_multi_init函数
    用户&权限
    HEOI2019 游记——240秒处的起死回生
    WPF 判断调用方法堆栈
    WPF 判断调用方法堆栈
  • 原文地址:https://www.cnblogs.com/fayin/p/8205300.html
Copyright © 2011-2022 走看看