object.observe 已于2016年被彻底移除,所有现代浏览器均不支持,调用会抛出 referenceerror;其被 proxy 取代,因后者能拦截更多操作并支持深层响应式,但需递归代理嵌套对象并注意内存泄漏。

Object.observe 在 2016 年已被彻底移除,所有现代浏览器(包括 Chrome 52+、Firefox、Safari、Edge)都不再支持。它不是“被弃用”,而是被删除——试图调用会直接抛出 ReferenceError: Object.observe is not defined。
为什么不能用 Object.observe 替代方案?
它依赖 V8 引擎早期的观察机制,与 ES6+ 的响应式设计哲学冲突:无法处理 Proxy 无法拦截的操作(如 in、delete、原型链变更),也不支持数组索引赋值的精确通知,更无法穿透嵌套对象。现代框架(Vue 3、Solid、Qwik)全量迁移到 Proxy 就是为了解决这些硬伤。
用 Proxy 实现等效的源码对象监控
核心思路是用 Proxy 包裹目标对象,拦截 set、deleteProperty、defineProperty 等关键操作,并手动触发回调。注意:Proxy 是浅层的,需递归代理嵌套对象才能覆盖深层变更。
常见错误现象:proxy.foo = { bar: 1 } 后修改 proxy.foo.bar = 2 不触发监听——因为 foo 的值是普通对象,未被代理。
实操建议:
- 对每个新赋值的 object/array 类型值,递归调用
createObservable再代理 - 避免代理已有 Proxy 对象(重复代理会丢失原始 trap)
- 监听函数需保存引用,否则无法
unsubscribe;可用WeakMap关联 target → handlers - 不拦截
get(除非需要计算属性),否则影响性能且破坏原语行为
简短示例:
function createObservable(obj, callback) {
const handler = {
set(target, key, value) {
const oldValue = target[key];
target[key] = value;
callback({ type: 'set', key, oldValue, newValue: value });
return true;
},
deleteProperty(target, key) {
const oldValue = target[key];
delete target[key];
callback({ type: 'delete', key, oldValue });
return true;
}
};
return new Proxy(obj, handler);
}
const state = { count: 0 };
const obs = createObservable(state, (change) => console.log(change));
obs.count = 1; // → { type: 'set', key: 'count', oldValue: 0, newValue: 1 }
兼容旧代码的最小迁移路径
如果你在维护遗留项目且曾重度依赖 Object.observe 的事件格式(如 add、update、reconfigure),不要尝试 polyfill——没有可靠方案。应聚焦三点:
- 将原有 observer 回调逻辑抽离为纯函数,接收
{ type, name, oldValue, newValue }形式参数 - 用
Proxy替换所有Object.observe(obj, callback)调用点 - 对数组操作单独处理:监听
push/pop等方法需包装原型方法,或改用Array.from()+Proxy拦截set(但无法捕获arr[0] = x这类稀疏索引写入)
注意:Proxy 无法监听属性是否被访问(get 可拦截但开销大),也不能捕获 Object.defineProperty 中 writable: false 等元属性变更——这些正是 Object.observe 当年也做不到的。
真正难的是深层嵌套对象的自动代理和内存泄漏控制,尤其是循环引用场景下 WeakMap 的键必须是原始对象引用,一旦被 GC 就失效。这点很容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











