JavaScript

JavaScript 知识量:26 - 101 - 483

8.3 代理模式><

跟踪属性访问- 8.3.1 -

在 JavaScript 中,可以通过 Proxy 对象来捕获对象属性的访问和查询操作。Proxy 对象提供了一种机制,可以在目标对象上定义一些拦截操作,例如访问或修改属性、查询或设置方法等。通过捕获get、set和has等操作,可以知道对象属性什么时候被访问、被查询。

以下是一个示例,演示如何使用 Proxy 对象来捕获对象属性的访问和查询操作:

const obj = {  
  name: 'Tom',  
  age: 25,  
  gender: 'male'  
};  
  
const handler = {  
  get(target, prop) {  
    console.log(`Reading ${prop}`);  
  },  
  set(target, prop, value) {  
    console.log(`Writing ${prop}: ${value}`);  
  },  
  has(target, prop) {  
    console.log(`Has property ${prop}? ${target.hasOwnProperty(prop)}`);  
    return target.hasOwnProperty(prop);  
  }  
};  
  
const proxyObj = new Proxy(obj, handler);  
  
// 访问属性  
console.log(proxyObj.name); // 输出 "Reading name" 和 "Tom"  
  
// 修改属性  
proxyObj.age = 26; // 输出 "Writing age: 26"  
  
// 检查是否有某个属性  
console.log(proxyObj.hasOwnProperty('age')); // 输出 "Has property age? true" 和 true

在这个示例中,首先定义了一个目标对象 obj,并创建了一个 handler 对象来处理属性的访问、修改和查询操作。然后,使用 new Proxy() 创建了一个代理对象 proxyObj,并将目标对象 obj 和处理器对象 handler 作为参数传递给构造函数。最后,通过代理对象 proxyObj 来访问和修改目标对象 obj 的属性。每当访问或修改属性时,处理器对象 handler 中对应的方法就会被调用,从而可以捕获这些操作并输出相关信息。

隐藏属性- 8.3.2 -

JavaScript 中的代理(Proxy)对象的内部实现对外部代码是不可见的。代理是一种特殊类型的对象,它可以在调用某些方法时自动执行一些额外的操作,而无需在代码中显式地编写这些操作。

通过定义代理的陷阱(trap)函数,可以控制某些操作的执行行为。例如,可以在陷阱函数中实现一些额外的操作,例如记录日志、验证输入值等等,而无需修改外部代码。

由于代理的陷阱函数是在内部实现的,因此它们对于外部代码是不可见的。这意味着可以在不修改外部代码的情况下,对对象的行为进行修改和增强。

以下是一个简单的示例,演示如何使用代理来对对象的属性进行访问控制:

const target = {  
  name: 'John',  
  age: 25  
};  
  
const handler = {  
  get(target, prop) {  
    if (prop === 'age') {  
      return target[prop];  
    } else {  
      throw new Error('Access denied');  
    }  
  }  
};  
  
const proxy = new Proxy(target, handler);  
  
console.log(proxy.age); // 25  
console.log(proxy.name); // "John"  
console.log(proxy.address); // Error: Access denied

在这个示例中,通过定义 handler 对象中的 get 陷阱函数来控制对 target 对象属性的访问。在 get 函数中,检查要访问的属性是否为 'age',如果是,则返回该属性的值;否则,抛出一个错误。

由于使用了代理,因此外部代码无法直接访问 target 对象的属性。如果要访问一个未授权的属性,例如 address,将会抛出一个错误,而无需修改外部代码。

属性验证- 8.3.3 -

JavaScript 中的 Proxy 对象提供了一种功能,可以在设置属性时触发自定义的行为。这主要通过 set 陷阱实现,该陷阱接受三个参数:目标对象、属性名和值。

以下是一个基本示例:

let obj = new Proxy({},{  
  set(target, prop, value) {  
    if(value < 0) {  
      console.log(`拒绝赋值: ${prop} = ${value}`);  
      return false;  // 拒绝赋值  
    } else {  
      console.log(`允许赋值: ${prop} = ${value}`);  
      return true;   // 允许赋值  
    }  
  }  
});  
  
obj.x = 10;  // 允许赋值: x = 10  
obj.y = -10; // 拒绝赋值: y = -10

在这个例子中,当尝试修改 obj 的属性时,set 方法会被调用。如果赋的值小于0,拒绝赋值并输出一条消息。反之,如果赋的值大于或等于0,允许赋值并输出一条消息。

需要注意的是,set 陷阱并不影响赋值的实际结果,而只是提供了在赋值时执行自定义逻辑的可能性。如果要阻止赋值对目标对象产生实际影响,需要在 set 方法中返回 false。这表示该操作未被成功执行。在上述例子中,当尝试将 y 赋值为 -10 时,由于值小于0,所以 set 方法返回 false,obj.y 的值仍然是 undefined。