返回

从观察者模式看Object.defineProperty 和 proxy 的异同

前端

引言

在 JavaScript 中,Object.defineProperty()Proxy 都是用于对象属性操作的工具。前者允许您向现有对象添加或修改属性,而后者则允许您创建动态代理对象,用于拦截和自定义对象的属性访问。

从观察者模式的角度来看,Object.defineProperty()Proxy 都可以被认为是观察者模式的实现。观察者模式是一种软件设计模式,它允许对象(即被观察者)将有关其内部状态的信息通知其他对象(即观察者)。

在本文中,我们将介绍 Object.defineProperty()Proxy 的区别和联系,并提供一些使用示例。

Object.defineProperty()Proxy 的区别

Object.defineProperty()Proxy 之间的主要区别在于,前者只能用于向现有对象添加或修改属性,而后者则可以用于创建动态代理对象,用于拦截和自定义对象的属性访问。

Object.defineProperty() 的语法如下:

Object.defineProperty(obj, prop, descriptor)

其中:

  • obj 是要添加或修改属性的对象。
  • prop 是要添加或修改的属性的名称。
  • descriptor 是一个对象,它指定了属性的符。

Proxy 的语法如下:

new Proxy(target, handler)

其中:

  • target 是要创建代理对象的目标对象。
  • handler 是一个对象,它指定了代理对象的行为。

Object.defineProperty()Proxy 的联系

Object.defineProperty()Proxy 都可以被认为是观察者模式的实现。观察者模式是一种软件设计模式,它允许对象(即被观察者)将有关其内部状态的信息通知其他对象(即观察者)。

Object.defineProperty() 中,对象本身是可观察者,而属性符则是观察者。当对象的属性值发生变化时,属性描述符就会被通知。

Proxy 中,目标对象是可观察者,而代理对象则是观察者。当目标对象属性被访问时,代理对象就会被通知。

Object.defineProperty()Proxy 的使用示例

Object.defineProperty()

// 创建一个对象
const person = {};

// 使用 Object.defineProperty() 向对象添加属性
Object.defineProperty(person, "name", {
  value: "John Doe",
  writable: true,
  enumerable: true,
  configurable: true
});

// 访问对象的属性
console.log(person.name); // "John Doe"

// 修改对象的属性值
person.name = "Jane Doe";

// 再次访问对象的属性
console.log(person.name); // "Jane Doe"

// 删除对象的属性
delete person.name;

// 再次访问对象的属性
console.log(person.name); // undefined

Proxy

// 创建一个目标对象
const person = {
  name: "John Doe",
  age: 30
};

// 创建一个代理对象
const proxy = new Proxy(person, {
  // 拦截属性的读取
  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;
  },

  // 拦截属性的删除
  deleteProperty: function(target, prop) {
    console.log(`Deleting property: ${prop}`);
    delete target[prop];
  }
});

// 访问对象的属性
console.log(proxy.name); // "John Doe" (Getting property: name)

// 修改对象的属性值
proxy.name = "Jane Doe"; // Setting property: name to Jane Doe

// 删除对象的属性
delete proxy.age; // Deleting property: age

// 再次访问对象的属性
console.log(proxy.age); // undefined (Getting property: age)

结论

Object.defineProperty()Proxy 都是 JavaScript 中用于对象属性操作的工具。前者只能用于向现有对象添加或修改属性,而后者则可以用于创建动态代理对象,用于拦截和自定义对象的属性访问。

从观察者模式的角度来看,Object.defineProperty()Proxy 都可以被认为是观察者模式的实现。

希望本文能够帮助您理解 Object.defineProperty()Proxy 的区别和联系。