了解ES6的proxy以及VUE源码对proxy的应用

首先先介绍一下proxy
proxy是ES6提供的一个构造函数。是用于过滤拦截和改写的。当外界对对象进行访问时,都必须通过这一层拦截,可以被过滤或者改写。
举一个例子:


    var proxy = new Proxy({},{
    get:function(target,property){
          return 35
    } 
  })
   proxy.time //35
   proxy.name //35

首先对象中的get方法是读取对象中的内容,无论读取什么都返回35
我创造了一个实例,传入目标对象是一个空对象(针对于上图例子所示),第二个参数是拦截它的函数,这里是无论访问这个对象任何属性都会范返回35。

那么我们在举一个完整的例子。

  var person = {
    name:'张三'
  }
  var proxy = new Proxy(preson, {
       get:function(target,property){
          if(property in target) {
            return target[property]
         }else {
           throw new ReferenceError("Property \"" + property + "\" dose not exist.");
         }
      }
  });
   proxy.name // '张三'
   proxy.age // 抛出错误

上面这一段代码就是。当我访问对象中存在的属性,可以正常返回我,但是当我访问对象中没有的属性就会返回一个空。也充分说明,这个proxy构造函数的作用。

说一下proxy的语法:

let p = new Proxy(target, handler);
参数:
target
用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个对象,其属性是当执行一个操作时定义代理的行为的函数。


基础例子
let handler = {
    get: function(target, name){
        return name in target ? target[name] : 37;
    }
};

let p = new Proxy({}, handler);

p.a = 1;
p.b = undefined;

console.log(p.a, p.b);    // 1, undefined

console.log('c' in p, p.c);    // false, 37

同样这个hander参数可以通过对象的get属性或者set属性对对象进行验证或者是过滤。

讲真我查了很多资料始终不太理解hander这个意思。根据MDN上的例子,也在这里说明一下。附上链接。
proxyMDN链接
如果我写的不明白,可以直接看网址哦。

然后我们看回VUE的源码:

路径:src/core/instance/proxy.js

节选部分内容关于proxy

  initProxy = function initProxy (vm) {
    if (hasProxy) {
      // determine which proxy handler to use
      const options = vm.$options
      const handlers = options.render && options.render._withStripped
        ? getHandler
        : hasHandler
      vm._renderProxy = new Proxy(vm, handlers)
    } else {
      vm._renderProxy = vm
    }
  }

行吧我研究半天,真没太理解它这段是啥意思,为什么要用options判断,又是render属性什么的。大概情况就是某种状态下用proxy,另外一种状态就是vue实例。

这里附上部分hasHandle的代码,可以说明,他是判断了部分信息。如果发生错误,当我们在开发环境下会有报错提示。warnReservedPrefix,warnNonPresent 则是提示信息的函数

 const hasHandler = {
    has (target, key) {
      const has = key in target
      const isAllowed = allowedGlobals(key) ||
        (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
      if (!has && !isAllowed) {
        if (key in target.$data) warnReservedPrefix(target, key)
        else warnNonPresent(target, key)
      }
      return has || !isAllowed
    }
  }
  
  文字提示报错方法 warnReservedPrefix :
 const warnReservedPrefix = (target, key) => {
    warn(
      `Property "${key}" must be accessed with "$data.${key}" because ` +
      'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
      'prevent conflicts with Vue internals. ' +
      'See: https://vuejs.org/v2/api/#data',
      target
    )
  }
 文字提示报错方法 warnNonPresent :
 const warnNonPresent = (target, key) => {
    warn(
      `Property or method "${key}" is not defined on the instance but ` +
      'referenced during render. Make sure that this property is reactive, ' +
      'either in the data option, or for class-based components, by ' +
      'initializing the property. ' +
      'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
      target
    )
  }

大概就是这个样子,因为看到很多信息说vue3.0更新了proxy,但是一直没有深入了解过这个到底是啥。看来es6还是很重要的~虽然平时用的比较多的都是数组或者对象的方法。文章中有借鉴es6入门这本书。等回青岛仔细看看之前买的vue源码的书关于proxy中内容会回来补充的。希望这篇文章可以帮到你们呢,虽然我也不是很厉害的大神呀。

另外的补充: Proxy 可以完美监听到任何方式的数据改变,唯一缺陷可能就是浏览器的兼容性不好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值