如何理解JS 中的Reflect 与 Proxy

591 阅读1分钟

本文举的例子来源:阮一峰es6教程

Reflect

字意上可以理解为反射。就像镜面反射一样,可以理解为一份虚的拷贝

举个例子:

var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },
}

Reflect.get(myObject, 'foo') // 1
Reflect.get(myObject, 'bar') // 2
Reflect.get(myObject, 'baz') // 3

Reflect还可接收第三个参数(receiver),把一个对象的东西映射到另外一个对象上,例子:

var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },
};

var myReceiverObject = {
  foo: 4,
  bar: 4,
};

Reflect.get(myObject, 'baz', myReceiverObject) // 8

Reflect最大的特点是可以映射一些明显属于语言内部的方法

比如上例就不能用call改写,因为call 拿不到对象的get属性

Proxy

let proxy = new Proxy(target, handler) // target 为目标对象,handle 为代理的操作

proxy会代理target 的某些操作的默认行为。等同于在语言层面做出修改

例子:

var obj = new Proxy({}, {
  get: function (target, propKey, receiver) {
    console.log(`getting ${propKey}!`);
    return Reflect.get(target, propKey, receiver);
  },
  set: function (target, propKey, value, receiver) {
    console.log(`setting ${propKey}!`);
    return Reflect.set(target, propKey, value, receiver);
  }
})

obj.count = 1
//  setting count!
++obj.count
//  getting count!
//  setting count!
//  2

上面这个例子就代理了obj读写的默认行为,相当于在语言层面对obj 的读写行为进行修改。

总结

Reflect可以获取目标对象的默认行为(例如getter,setter),而Proxy可以代理(覆盖)目标对象的默认行为。

无论Proxy怎么代理默认行为,总是可以通过Reflect对应的方法获取原始的默认行为。上例中Reflect起到的作用就是把get的默认行为再加到我们自己定义的get中。

ReflectProxy都是是 ES6 为了操作对象(获取和修改原生行为的能力)而提供的新 API。