proxy 的 set 捕获器必须返回布尔值,true 表示赋值成功并继续执行,false 表示拒绝赋值(严格模式下抛 typeerror);非布尔返回值或无返回等同于 false。

Proxy 的 set 捕获器必须返回布尔值,这是 JavaScript 引擎强制执行的约定,不是可选规范。返回 true 表示赋值操作被接受并完成;返回 false 表示拒绝赋值,在严格模式下会立即抛出 TypeError。
为什么 set 必须返回布尔值
这个返回值是 JS 引擎判断赋值是否“成功落地”的唯一依据。它不关心你内部有没有真正写入、有没有做校验或日志,只看这个布尔信号:
- 返回
true→ 引擎认为属性已设置,继续执行后续代码 - 返回
false→ 引擎中断当前赋值,抛出错误(仅严格模式下必然报错;非严格模式可能静默失败,但行为不可靠,应避免) - 不返回值、返回非布尔值(如
undefined、1、"ok")→ 等同于false,同样触发错误
如何正确实现 set 并保证返回值合规
最稳妥的方式是委托给 Reflect.set(),因为它天然返回布尔值,且语义一致:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
-
Reflect.set(target, key, value, receiver)成功时返回true,失败时返回false - 直接用
target[key] = value赋值后手动return true也可行,但无法自动处理 setter 访问器、不可写属性等边界情况 - 若需拦截逻辑(如校验、日志),应在调用
Reflect.set前后添加,但最终return必须是它的结果或明确的布尔值
receiver 参数对返回值无直接影响,但影响 setter 内部 this
receiver 不参与返回值判定,但它决定当目标对象属性是访问器(getter/setter)时,其中 this 指向谁。例如:
- 目标
obj有set name(val) { console.log(this) } - 用
Reflect.set(obj, 'name', 'x', obj1)→this指向obj1 - 省略
receiver→this指向obj - 无论
this指向谁,Reflect.set的返回值仍只反映赋值是否实际生效
其他常见捕获器的返回值规律
并非所有捕获器都像 set 那样强约束返回布尔值,但各有规则:
-
get:返回值即属性读取结果,无类型限制 -
has:必须返回布尔值(决定in操作符结果) -
deleteProperty:必须返回布尔值(决定delete是否成功) -
setPrototypeOf、preventExtensions、isExtensible等:均要求布尔返回值 - 多数捕获器若未显式返回,或返回非预期类型,会导致运行时异常或静默降级










