美文网首页
摒弃Object.defineProperty,基于 Proxy

摒弃Object.defineProperty,基于 Proxy

作者: 时间的溺水者 | 来源:发表于2020-05-12 16:37 被阅读0次

为什么要取代Object.defineProperty

Object.defineProperty的缺点:

1、无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。 为了解决这个问题,经过vue内部处理后可以使用以下几种方法来监听数组

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

2、Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择。

而要取代它的Proxy有以下两个优点:

可以劫持整个对象,并返回一个新对象
有13种劫持操作

Proxy

Proxy是 ES6 中新增的一个特性,翻译过来意思是"代理",用在这里表示由它来“代理”某些操作。

Proxy 让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

使用 Proxy 的核心优点是可以交由它来处理一些非核心逻辑(如:读取或设置对象的某些属性前记录日志;设置对象的
某些属性值前,需要验证;某些属性的访问控制等)。 从而可以让对象只需关注于核心逻辑,达到关注点分离,降低对
象复杂度等目的。

基本用法:

let p = new Proxy(target, handler);

target 是用Proxy包装的被代理对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler 是一个对象,其声明了代理target 的一些操作,其属性是当执行一个操作时定义代理的行为的函数。

p 是代理后的对象。当外界每次对 p 进行操作时,就会执行 handler 对象上的一些方法。Proxy共有13种劫持操作,handler代理的一些常用的方法有如下几个:

get:读取
set:修改
has:判断对象是否有该属性
construct:构造函数

示例:


let obj = {};
let handler = {
  get(target, property) {
  console.log(`${property} 被读取`);
  return property in target ? target[property] : 3;
  },
  set(target, property, value) {
  console.log(`${property} 被设置为 ${value}`);
  target[property] = value;
  }
}
 
 let p = new Proxy(obj, handler);
 p.name = 'tom' //name 被设置为 tom
 p.age; //age 被读取 3

p 读取属性的值时,实际上执行的是 handler.get() :在控制台输出信息,并且读取被代理对象 obj 的属性。

p 设置属性值时,实际上执行的是 handler.set() :在控制台输出信息,并且设置被代理对象 obj 的属性的值。

基于Proxy来实现双向绑定

用Proxy来实现一个经典的双向绑定todolist,首先简单的写一点html结构:

<div id="app">
      <input type="text" id="input" />
      <div>您输入的是: <span id="title"></span></div>
      <button type="button" name="button" id="btn">添加到todolist</button>
      <ul id="list"></ul>
 </div>

相关文章

网友评论

      本文标题:摒弃Object.defineProperty,基于 Proxy

      本文链接:https://www.haomeiwen.com/subject/aftonhtx.html