reactive返回Proxy代理对象,与原对象不相等;ref包装任意类型并提供.value访问,支持基础值与对象,解构需toRefs,模板中自动解包。

因为 Proxy 代理对象和原对象是两个完全不同的内存实例,即使内容一模一样,=== 比较的是引用地址,不是结构或值。
Proxy 对象没有“身份继承”
Proxy 创建的是一个全新对象,它只是在内部持有对目标对象的引用,自身不等于目标对象,也不等于另一个用相同目标创建的 Proxy 实例:
const obj = { a: 1 };const p1 = new Proxy(obj, {});const p2 = new Proxy(obj, {});-
p1 === p2 // false(不同代理实例) -
p1 === obj // false(代理 ≠ 原对象)
instanceof 和 constructor 也会失效
Proxy 拦截了原型链相关操作,导致常规类型判断不可靠:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
-
p1 instanceof Object // false(Proxy.prototype 是 undefined) p1.constructor === Object // false- 不能依赖
Object.prototype.toString.call(p1)获取准确类型标识
想比“是不是同一个代理”?只能靠手动标记
如果业务中真需要识别某个特定 Proxy 实例(比如缓存、防重复代理),得自己加标识:
- 创建时挂载唯一 id:
const proxy = new Proxy(target, { id: Symbol('user-proxy') }) - 或用 WeakMap 存储映射:
const proxyIdMap = new WeakMap(); proxyIdMap.set(proxy, 'user-form-1') - 避免用
JSON.stringify或深比较代替 ===,那解决的是值相等,不是身份问题
Vue3 里尤其容易踩这个坑
比如你在 setup 中写了 const state = reactive({ x: 1 }),然后误判:
if (state === props.initialState) {...} // 总是 false,即使初始值一样- 正确做法是比内容(
isDeepEqual(state, props.initialState))或比来源标识(如传入的 key / id) - watch 或 computed 依赖项里也别混用原对象和其 reactive 版本,否则响应式会断链

















