用 proxy 的 get 陷阱拦截属性访问,通过 key in target 或 hasownproperty 检查属性是否存在,避免误判 undefined 值;缺失时抛出带上下文的 referenceerror,含属性名和构造函数名,receiver 参数需保留签名以兼容 reflect 调用。

用 Proxy 实现属性访问拦截并抛出友好错误,核心是定义 get 陷阱,在读取不存在的属性时主动 throw 错误,而不是返回 undefined。
明确检查属性是否存在
不能只靠 target[key] === undefined 判断,因为属性值本身可能是 undefined。应使用 key in target 或 Object.prototype.hasOwnProperty.call(target, key) 确保判断的是“是否声明”,而非“是否有值”。
-
key in target:检查自身 + 原型链上的自有/继承属性 -
hasOwnProperty:仅检查对象自身的属性(更严格,推荐用于强约束场景)
在 get 中统一抛错,消息带上下文
错误信息要包含目标对象标识、缺失属性名,便于调试。避免笼统的 "Property not found"。
- 可拼接
target.constructor?.name || 'Object'增加类型提示 - 用
ReferenceError更语义化(访问未声明变量也抛这个) - 示例:
throw new ReferenceError(`Property '${key}' does not exist on ${target.constructor?.name || 'Object'}`)
注意 receiver 参数的用途
receiver 是当前 proxy 实例(或继承链中的调用者),在实现继承式拦截或需要保持 this 指向时很重要。若只是简单校验,通常不需直接使用它,但必须保留参数签名(get(target, key, receiver)),否则 Reflect 调用可能出错。
- 若后续要用
Reflect.get(target, key, receiver)转发读取,receiver 必须传入,否则 this 绑定会丢失 - 错误提示中一般不依赖 receiver,但写法要规范
完整可运行示例
const person = { name: 'Alice', age: 30 };
const safeProxy = new Proxy(person, {
get(target, key) {
if (key in target) {
return target[key];
}
throw new ReferenceError(`Property '${key}' is not defined on person`);
}
});
console.log(safeProxy.name); // Alice
console.log(safeProxy.email); // 抛出 ReferenceError











