JavaScript中setter设置新值时获取hoveredElement旧值的问题
问题分析与解决
你的问题核心在于旧值的保存时机完全错了,当前写法只在注册监听的瞬间存了一次初始空对象,之后每次修改hoveredElement时都没有更新旧值,自然日志里始终显示空对象。另外还需要注意引用类型的拷贝问题,我给你一步步拆解并修复:
问题根源
- 你在
registerListener里给oldHoveredElement赋值,这只会在注册监听的那一刻把当时的_hoveredElement(也就是初始空对象)存进去,后续修改hoveredElement时,这个旧值不会自动同步更新。 _hoveredElement是引用类型,就算后续想手动更新,直接赋值会导致新旧值指向同一个对象,也拿不到真正的旧状态。
修复后的代码
把旧值的保存逻辑移到hoveredElement的setter里,每次设置新值前先存好当前旧值,再更新新值并触发监听,同时把新旧值直接作为参数传给监听函数,避免this指向混乱的问题:
let hoverEvent = { _hoveredElement: {}, _listener: function(newVal, oldVal) {}, set hoveredElement(val) { // 浅拷贝旧值,避免引用关联 const oldVal = { ...this._hoveredElement }; // 更新新值 this._hoveredElement = val; // 触发监听时同时传递新旧值 this._listener(val, oldVal); }, get hoveredElement() { return this._hoveredElement; }, registerListener: function(listener) { this._listener = listener; } } hoverEvent.registerListener(function(newVal, oldVal) { console.log("Someone changed the value of hoveredElement to ", newVal); console.log("from ", oldVal); }); // 测试验证 hoverEvent.hoveredElement = { id: 1, name: "test-element" }; hoverEvent.hoveredElement = { id: 2, name: "new-hover-element" };
额外说明
- 用
{ ...this._hoveredElement }做浅拷贝是为了避免旧值和新值指向同一个对象,如果你的_hoveredElement是嵌套复杂对象,需要用深拷贝(比如JSON.parse(JSON.stringify(...))或者专门的深拷贝工具函数)。 - 直接把新旧值作为参数传给监听函数,比依赖
this获取旧值更可靠,能规避箭头函数/普通函数的this指向差异问题。
内容的提问来源于stack exchange,提问作者Apbln
相关产品推荐
相关产品推荐

