get 和 set 陷阱
自定义属性的读取和写入行为。
get 和 set 陷阱 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。
get 和 set 拦截器
get 和 set 拦截器是最常用的代理钩子。它们会拦截属性的读取和写入,让您能够转换值、验证输入或记录访问。
get 拦截器签名
get(target, property, receiver) 会在每次读取属性时运行。调用方能看到什么值,由您返回什么决定。
const proxy = new Proxy({ price: 10 }, {
get(target, prop) {
return target[prop];
}
});
console.log(proxy.price);通过 get 提供默认值
get 拦截器可以为缺失属性提供 fallback,而不是返回 undefined。
const proxy = new Proxy({ a: 1 }, {
get(target, prop) {
return prop in target ? target[prop] : 0;
}
});
console.log(proxy.a);
console.log(proxy.missing);转换读取到的值
get 拦截器可以在值返回时调整其形式,例如将字符串转换为大写。
const proxy = new Proxy({ name: 'ada' }, {
get(target, prop) {
const value = target[prop];
return typeof value === 'string' ? value.toUpperCase() : value;
}
});
console.log(proxy.name);set 拦截器签名
set(target, property, value, receiver) 会在每次写入时运行。成功时必须返回 true,否则严格模式会抛出异常。
const proxy = new Proxy({}, {
set(target, prop, value) {
target[prop] = value;
return true;
}
});
proxy.x = 5;
console.log(proxy.x);在 set 中进行验证
set 拦截器的经典用途是验证:在无效值到达 target 之前拒绝它们。
const person = new Proxy({}, {
set(target, prop, value) {
if (prop === 'age' && (typeof value !== 'number' || value < 0)) {
throw new TypeError('age must be a non-negative number');
}
target[prop] = value;
return true;
}
});
person.age = 30;
console.log(person.age);
try { person.age = -5; } catch (e) { console.log(e.message); }在 set 中强制转换值
除了拒绝值之外,set 拦截器还可以规范化输入,例如在存储字符串之前先去除首尾空白。
const proxy = new Proxy({}, {
set(target, prop, value) {
target[prop] = typeof value === 'string' ? value.trim() : value;
return true;
}
});
proxy.name = ' Ada ';
console.log('[' + proxy.name + ']');记录两种操作
结合使用 get 和 set 可以跟踪每次访问。这对于调试对象的使用方式非常有价值。
const proxy = new Proxy({ v: 1 }, {
get(target, prop) {
console.log('GET ' + prop);
return target[prop];
},
set(target, prop, value) {
console.log('SET ' + prop + ' = ' + value);
target[prop] = value;
return true;
}
});
proxy.v = 42;
console.log(proxy.v);强制实现只读
始终拒绝写入的 set 拦截器会将代理变成 target 的只读视图。
const readonly = new Proxy({ pi: 3.14 }, {
set() {
console.log('writes are blocked');
return false;
}
});
try {
'use strict';
readonly.pi = 0;
} catch (e) {
console.log(e.name);
}
console.log(readonly.pi);Symbol 键和内部机制
符号键同样会触发拦截器。请注意:记录包括内部符号在内的每个属性可能会产生大量噪声,因此请在需要时进行筛选。
const proxy = new Proxy({ a: 1 }, {
get(target, prop) {
if (typeof prop === 'string') console.log('reading ' + prop);
return target[prop];
}
});
console.log(proxy.a);get 和 set 为何重要
这两个拦截器结合起来,可以在不修改 target 的情况下实现验证、计算属性、默认值、日志记录和响应式行为。不过,在拦截器内部手动编写 target[prop] = value 存在一些边界情况。下一节介绍的 Reflect API 可以正确处理这些情况。
const tracked = new Proxy({ total: 0 }, {
set(target, prop, value) {
console.log(prop + ' changed to ' + value);
target[prop] = value;
return true;
}
});
tracked.total = 100;
console.log(tracked.total);快速检查
set 拦截器必须返回什么,才能表示赋值成功?
回顾:get 和 set 拦截器
您学会了代理对象的核心拦截器:
get(target, prop, receiver)会拦截读取;您可以返回任意值。set(target, prop, value, receiver)会拦截写入;成功时返回true。- 您可以使用它们实现默认值、转换、验证和日志记录。
- 要在拦截器内部正确处理操作,请使用下一节介绍的
Reflect。
常见问题解答
「get 和 set 陷阱」课时是免费的吗?
是的 — 「get 和 set 陷阱」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。
「get 和 set 陷阱」这节课中我会学到什么?
自定义属性的读取和写入行为。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 JavaScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「get 和 set 陷阱」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 JavaScript Academy 课中编写并运行代码吗?
能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 创建 Proxy
- get 和 set 陷阱
- Reflect API
- Proxy 的实际应用场景