跳到主要内容

JavaScript 代理(Proxies)

提示
  1. 代理对象概念:JavaScript的代理对象(Proxy)用于包装对象或函数,重新定义各种操作(如读取、插入、验证等),添加自定义行为。
  2. 创建和使用代理:使用new Proxy(target, handler)创建代理,其中target是要代理的对象或函数,handler定义对象的自定义行为。
  3. 代理的应用场景:代理可用于验证、创建对象的只读视图,或在满足特定条件时触发副作用。

在 JavaScript 中,代理(代理对象)用于包装一个对象并重新定义对该对象的各种操作,如读取、插入、验证等。代理允许你为对象或函数添加自定义行为。

创建代理对象

代理的语法是:

new Proxy(target, handler);

这里,

  • new Proxy() - 构造函数。
  • target - 你想代理的对象/函数。
  • handler - 可以重新定义对象的自定义行为。

例如,

let student1 = {
age: 24,
name: "Felix",
};

const handler = {
get: function (obj, prop) {
return obj[prop] ? obj[prop] : "property does not exist";
},
};

const proxy = new Proxy(student1, handler);
console.log(proxy.name); // Felix
console.log(proxy.age); // 24
console.log(proxy.class); // property does not exist

这里,get() 方法用于访问对象的属性值。如果对象中没有该属性,它返回 property does not exist。

如你所见,你可以使用代理为对象创建新的操作。当你想检查一个对象是否有特定的键并根据该键执行操作时,可以使用代理。

你也可以传递一个空的处理器。当传递空处理器时,代理的行为就像原始对象一样。例如,

let student = {
name: "Jack",
age: 24,
};

const handler = {};

// 传递空处理器
const proxy1 = new Proxy(student, {});

console.log(proxy1); // Proxy {name: "Jack", age: 24}
console.log(proxy1.name); // Jack

代理处理器

代理提供了两个处理器方法 get()set()

get() 处理器

get() 方法用于访问目标对象的属性。例如,

let student = {
name: "Jack",
age: 24,
};

const handler = {
// 获取对象键和值
get(obj, prop) {
return obj[prop];
},
};

const proxy = new Proxy(student, handler);
console.log(proxy.name); // Jack

这里,get() 方法接受对象和属性作为其参数。

set() 处理器

set() 方法用于设置对象的值。例如,

let student = {
name: "John",
};

let setNewValue = {
set: function (obj, prop, value) {
obj[prop] = value;
return;
},
};

// 设置新代理
let person = new Proxy(student, setNewValue);

// 设置新的键/值
person.age = 25;
console.log(person); // Proxy {name: "John", age: 25}

这里,新属性 age 被添加到 student 对象中。

代理的用途

1. 用于验证

你可以使用代理进行验证。你可以检查键的值并根据该值执行操作。

例如,

let student = {
name: "Jack",
age: 24,
};

const handler = {
// 获取对象键和值
get(obj, prop) {
// 检查条件
if (prop == "name") {
return obj[prop];
} else {
return "Not allowed";
}
},
};

const proxy = new Proxy(student, handler);
console.log(proxy.name); // Jack
console.log(proxy.age); // Not allowed

这里,只有 student 对象的 name 属性是可访问的。否则,它返回 Not allowed。

2. 对象的只读视图

有时你可能不想让其他人更改对象。在这种情况下,你可以使用代理使对象只读。例如,

let student = {
name: "Jack",
age: 23,
};

const handler = {
set: function (obj, prop, value) {
if (obj[prop]) {
// 不能更改 student 的值
console.log("Read only");
}
},
};

const proxy = new Proxy(student, handler);

proxy.name = "John"; // Read only
proxy.age = 33; // Read only

在上述程序中,无法以任何方式更改对象。

如果有人试图以任何方式更改对象,你只会收到一个字符串,说 Read Only。

3. 副作用

当满足条件时,你可以使用代理来调用另一个函数。例如,

const myFunction = () => {
console.log("execute this function");
};

const handler = {
set: function (target, prop, value) {
if (prop === "name" && value === "Jack") {
// 调用另一个函数
myFunction();
} else {
console.log("Can only access name property");
}
},
};

const proxy = new Proxy({}, handler);

proxy.name = "Jack"; // execute this function
proxy.age = 33; // Can only access name property

JavaScript 代理从 JavaScript ES6 版本开始引入。一些浏览器可能不完全支持其使用。要了解更多,请访问 JavaScript 代理