proxy 和 Object.defineProject 的区别

  1. Object.defineProject 只有一次劫持一个对象中的属性,所以一般劫持对象是需要遍历劫持的,而proxy 直接劫持整个对象
  2. Object.defineProject 监听不到数组长度的变化,需要进行一些 hack , 而 Proxy 不需要那么多hack,就可以无压力监听数组的变化,我们都知道,标准永远优先于hack。
  3. Proxy 最大的劣势就是他的兼容性问题,

proxy 是用来干什么的

  • proxy 就是一个代理,用来帮我们做对数据的处理,构造函数的处理,对数据的验证,说白了,就是在外面访问对象前添加了一层拦截,可以过滤很多操作,而这些过滤由你定义;

    1. let p = new Proxy(target, handler);
    2. /**
    3. * target:需要使用Proxy包装的目标对象
    4. *(可以使任何类型的对象,包括原生数组,函数,甚至另一个代理)
    5. * handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数
    6. */
    7. let test = {
    8. name: "小红"
    9. };
    10. test = new Proxy(test, {
    11. get(target, key) {
    12. console.log('获取了getter属性');
    13. return target[key];
    14. }
    15. // target是这个对象,key是键名,value是要修改的新值
    16. set(target, key, value) {
    17. if (key === "age" && typeof value !== "number") {
    18. throw Error("age字段必须为Number类型");
    19. }
    20. return Reflect.set(target, key, value);
    21. }
    22. });
    23. console.log(test.name);
    24. // 结果是 先打印 ‘获取了getter属性’这句话,然后打印小红。

    代理就是实现响应式数据的关键,因为一但数据被代理,那么拿数据的时候就会执行get方法,修改数据的时候就会执行set方法,如果你在set或者get里面添加一些操作,那么一但这个方法被触发,你添加的操作也会被触发

Proxy 一般和Reflect配套使用

Reflect 是什么 ?

  • 首先这个概念是ES6提出来的,为了操作对象而提供的API ,以下的熟知
    Reflect对象是一个全局的普通的对象。Reflect的原型就是Object.
  1. 将Object对象的一些明显属于语言内部的方法(比如Obejcet.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object喝Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从reflect对象上可以拿到语言内部的方法。
  2. 在使用Object.defineProperty(obj,name,desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj,name,desc)则会返回false。
  3. 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj,name)和Reflect.deleteProperty(obj,name)让它们变成了函数行为。
  4. Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。