使用Proxy实现可观察数组后丢失Array功能,如何仅监听push方法?
解决Proxy监听数组push同时保留原有功能的问题
嘿,我明白你遇到的问题了——你现在的Proxy只处理了push方法,但其他数组属性(比如length、索引值)在get陷阱里没有返回,自然就无法正常访问了。而且你还提到不想用两个数组,那我们只需要调整Proxy的get陷阱逻辑,让它在不是push的情况下,直接返回数组原本的属性/方法就行。
先看修正后的代码:
function observableArray(arr, callback) { console.log('create observableArray'); return new Proxy(arr, { get: function(target, prop) { // 当访问的是push方法时,我们重写它 if (prop === 'push') { return function(...args) { console.log('pushed elements', args); // 先执行原生的push操作 const result = Array.prototype.push.apply(target, args); // 触发回调通知 callback(); return result; } } // 其他所有属性/方法,直接返回原数组的对应值 // 用Reflect.get比直接target[prop]更稳妥,能正确处理继承属性和特殊情况 return Reflect.get(target, prop); } }); } // 测试代码 var list = [1, 2, 3]; list = observableArray(list, function() { console.log('push操作被触发了!'); }); list.push(4); console.log('list:', list); // 现在能正常输出 [1,2,3,4] console.log('length:', list.length); // 输出4 for(var i = 0; i < list.length; i++) { console.log(list[i]); // 依次输出1、2、3、4 }
关键调整点:
- 完善get陷阱的返回逻辑:之前的代码只处理了
push的情况,其他属性都没有返回,现在我们在默认分支用Reflect.get(target, prop)来返回原数组的所有原生属性和方法,这样length、索引访问、还有数组的其他方法(比如pop、slice)都能正常使用。 - 触发回调函数:你原来的代码里定义了callback但没调用,现在在push执行后触发它,这样就能监听到push操作了。
- 使用扩展参数
...args:原生push可以接收多个参数(比如list.push(4,5,6)),用...args能兼容这种情况,比单个elem参数更灵活。
这样修改后,既实现了只监听push方法的需求,又完全保留了数组的所有原生功能,而且不需要额外维护第二个数组,完美符合你的要求~
内容的提问来源于stack exchange,提问作者Goowik
相关产品推荐
相关产品推荐

