【重读红宝书(JS高程4)】第9章-代理与反射

86 阅读1分钟

这是重读红宝书(JavaScript高级程序设计 第4版)的第8篇文章,本节我们来看看代理:Proxy、Reflect,两者结合如何拦截访问属性、设置属性、删除属性、函数调用、new对象等

本节涉及源码见仓库 github.com/adamswan/Re…

通过 handler 的 get() 函数拦截

let one = {
  name: "高圆圆",
};

let p = new Proxy(one, {
  get(target, key, receiver) {
    console.log("触发get行为");
    console.log("target:", target);
    console.log("key:", key);
    console.log("receiver:", receiver);
    return Reflect.get(target, key, receiver);
  },
});

p.name;

2、拦截 set 行为

通过 handler 的 set() 函数拦截

let one = {
  name: "刘亦菲",
};

let p = new Proxy(one, {
  set(target, key, value, receiver) {
    console.log("触发set行为");
    console.log("target:", target);
    console.log("key:", key);
    console.log("value:", value);
    console.log("receiver:", receiver);

    return Reflect.set(target, key, value, receiver);
  },
});

p.name = "刘亦菲2";

3、拦截 in 操作符

通过 handler 的 has() 函数拦截

let one = {
  name: "周子琰",
};

let p = new Proxy(one, {
  has(target, key) {
    console.log("触发 in 操作符");

    return Reflect.has(target, key);
  },
});

console.log("name" in p);

4、拦截 Object.defineProperty

通过 handler 的 defineProperty() 函数拦截

let one = {
  name: "高圆圆",
};

let p = new Proxy(one, {
  defineProperty(target, property, descriptor) {
    console.log("触发 Object.defineProperty()");
    return Reflect.defineProperty(target, property, descriptor);
  },
});

Object.defineProperty(p, "age", { value: "18" });

console.log(p);

5、拦截 delete 操作符

通过 handler 的 deleteProperty() 函数拦截

let one = {
  name: "高圆圆",
};

let p = new Proxy(one, {
  deleteProperty(target, property) {
    console.log("拦截 delete 操作");
    return Reflect.deleteProperty(...arguments);
  },
});

delete p.name;

6、拦截 Object.keys() 操作

通过 handler 的 ownKeys() 函数拦截

let one = {
  name: "刘亦菲",
};

let p = new Proxy(one, {
  ownKeys(target) {
    console.log("触发 Object.keys()");
    return Reflect.ownKeys(...arguments);
  },
});

Object.keys(p);

7、拦截函数调用

通过 handler 的 apply() 函数拦截

function getName() {
  console.log("高圆圆");
}

let p = new Proxy(getName, {
  apply(target, thisArg, ...argumentsList) {
    console.log("getName被调用了");
    return Reflect.apply(...arguments);
  },
});

p();

8、拦截 new 操作符

通过 handler 的 construct() 函数拦截

function Wife() {
  this.name = "刘亦菲";
}

let p = new Proxy(Wife, {
  construct(target, argumentsList, newTarget) {
    console.log("new 被触发了");
    return Reflect.construct(...arguments);
  },
});

new p();