【TypeScript】Proxy 和 Reflect

在 TypeScript (TS) 中,Proxy 和 Reflect 是两个与元编程(metaprogramming)和对象操作相关的核心特性。

它们一起提供了对象操作和拦截功能,便于捕获和修改对象的行为。

proxy (代理) 和 Reflect (反射) 参数一样。

基本用法

Proxy

Proxy 是一个内置的构造函数,用于创建代理对象。代理对象允许你定义一个叫做"陷阱"(trap)的函数,这些陷阱会拦截对目标对象的操作。这些操作包括读取属性、写入属性、调用方法等等。通过使用代理,你可以在对象的行为上插入自定义逻辑或拦截这些操作。

let person = { name: 'xx', age: 20 }
// proxy 支持对象,数组,函数,set,map
// 代理对象的常用模式:前面一个对象,后面一个对象用于描述前面的对象
person.name // 取值
person.name = 'xxx' // 赋值
let personProxy = new Proxy(person, {
  // 拦截取值
  get(person, prop) {
	console.log(`getting ${prop} property`)
	return person[prop]
  },
  // 拦截赋值 person name xxx
  set(target, key, value, receiver) {

    return true
  },
  // 拦截函数调用
  apply() {

  },
  // 拦截 in 操作符
  has () {

  },
  // 拦截 for in 
  ownKeys() {

  },
  // 拦截 new 操作符
  construct() {

  },
  // 拦截删除的操作
  deleteProperty(target, p) {

  }
})

console.log(person.name) // 输出:“getting name property”,然后输出 “xxx”

Reflect

Reflect 是一个内置的对象,它提供了一组静态方法,用于执行一些与对象相关的默认操作。这些方法与代理对象一起使用,通常在陷阱中调用,以便在执行默认操作的同时添加自定义逻辑。

以下是一些常见的 Reflect 方法和它们的用法:

  • Reflect.get(target, propertyKey, receiver): 用于获取目标对象的属性值。
  • Reflect.set(target, propertyKey, value, receiver): 用于设置目标对象的属性值。
  • Reflect.has(target, propertyKey): 检查目标对象是否具有指定属性。
  • Reflect.deleteProperty(target, propertyKey): 用于删除目标对象的属性。
  • Reflect.construct(target, argumentsList, newTarget): 用于创建一个新的对象实例。
  • Reflect.apply(target, thisArg, argumentsList): 用于调用目标对象的方法。
let person = { name: 'xx', age: 20 }

const target = { name: 'John' };
// 输出 age 的值
// console.log(Reflect.get(person, 'age', person)); 
// 修改 age 的值,返回 true
// console.log(Reflect.set(person, 'age', 23, person));

let personProxy = new Proxy(person, {
  get(target, key, receiver) {
    if (target.age < 18) {
      return Reflect.get(target, key, receiver)
    } else {
      return "xx 成年了"
    }
  }
})

const proxy = new Proxy(target, {
  get(target, prop) {
    console.log(`Getting ${prop} property`);
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    console.log(`Setting ${prop} property to ${value}`);
    return Reflect.set(target, prop, value);
  }
});

// age:17 输出:17  age:20 输出:xx 成年了
console.log(personProxy.age);

proxy.name = 'Alice'; // 输出: "Setting name property to Alice"
console.log(proxy.name); // 输出: "Getting name property",然后输出 "Alice"

实现观察者模式(简易版)

// 存储回调函数(观察者)的集合
const list: Set<Function> = new Set()
const autorun = (cb: Function) => {
  if (!list.has(cb)) {
    list.add(cb)
  }
}
const observable = <T extends object>(params: T) => {
  return new Proxy(params, {
    set(target, key, value, receiver) {
      const result = Reflect.set(target, key, value, receiver)
      list.forEach(fn => fn())
      return result
    }
  })
}
// personProxy 对象被创建,开始时 list 为空。
const personProxy = observable({ name: 'xx', attr: "newbee" })
autorun(() => {
  console.log("有变换了");
})
// 输出两遍 有变化了
// 修改 personProxy.attr 属性,触发 Proxy 的 set 方法,该方法会遍历 list 集合并调用已注册的回调函数,输出 "有变化了"
personProxy.attr = "no-newbee"
personProxy.name = 'xxx'
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
TypeScript 中的代理(Proxy)是一种机制,它允许你拦截并自定义对象的操作。通过使用代理,你可以在对象的属性访问、赋值、函数调用等操作之前或之后执行自定义逻辑。这为你提供了更大的灵活性和控制力。 要创建一个代理对象,你可以使用 `Proxy` 构造函数。它接受两个参数:目标对象和一个处理程序对象(也称为代理处理器)。代理处理程序是一个包含各种钩子方法的对象,用于拦截和处理不同的操作。 下面是一个简单的示例,演示如何使用 TypeScript 创建一个代理对象: ```typescript const target = { name: "John", age: 30 }; const handler = { get: function(target, prop) { console.log(`Getting property ${prop}`); return target[prop]; }, set: function(target, prop, value) { console.log(`Setting property ${prop} to ${value}`); target[prop] = value; } }; const proxy = new Proxy(target, handler); console.log(proxy.name); // 输出:Getting property name,John proxy.age = 35; // 输出:Setting property age to 35 console.log(proxy.age); // 输出:Getting property age,35 ``` 在上面的示例中,我们创建了一个名为 `target` 的普通对象,它具有 `name` 和 `age` 两个属性。然后,我们定义了一个代理处理程序 `handler`,其中包含了 `get` 和 `set` 两个钩子方法。在这些方法中,我们可以自定义对象的属性访问和赋值行为。最后,我们使用 `new Proxy` 创建了一个代理对象 `proxy`,并对其进行了一些操作。 注意:由于 TypeScriptJavaScript 的超集,上述示例中的代码也适用于 JavaScript 环境。 希望这个简单的示例能够帮助你理解 TypeScript 中的代理概念和用法。如果你有更多问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小秀_heo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值