无法修改类时,如何让预调用函数返回数组同步静态字段的修改后数据?
问题描述
现有不可修改的WalmartCart类代码如下:
class WalmartCart { static cart = [] putItem(item){ WalmartCart.cart.push(item) } }
需要实现函数func,代码框架如下:
const func = (WalmartCart) => {}
该函数需满足以下要求:
- 仅能在向cart添加元素前调用一次
- 接收
WalmartCart类作为入参 - 返回的数组需自动为后续通过
putItem添加的每个元素新增指定字段(如'some new data': 'new data')
示例效果如下:
let result = func(WalmartCart) // 仅调用一次 let wal = new WalmartCart() wal.putItem( {'1': 1} ) wal.putItem( {'2': 2} ) wal.putItem( {'3': '3'} ) console.log(result) // 输出结果: // [ // {'1': 1, 'some new data': 'new data'}, // {'2': 2, 'some new data': 'new data'}, // {'3': '3', 'some new data': 'new data'} // ]
解决方案
可以通过重写putItem原型方法或用Proxy拦截cart数组的push操作实现需求,以下是两种可行方案:
方案一:重写putItem原型方法
直接拦截putItem的调用逻辑,处理元素后再执行原方法:
const func = (WalmartCart) => { // 初始化要返回的结果数组 const enhancedCart = []; // 保存原有的putItem方法 const originalPutItem = WalmartCart.prototype.putItem; // 重写putItem方法 WalmartCart.prototype.putItem = function(item) { // 创建新对象合并原元素与指定字段,避免修改原item const enhancedItem = { ...item, 'some new data': 'new data' }; // 将增强后的元素加入结果数组 enhancedCart.push(enhancedItem); // 调用原putItem方法,若需要原静态cart存增强后的元素,就传enhancedItem;否则传item originalPutItem.call(this, enhancedItem); }; return enhancedCart; };
方案二:用Proxy拦截cart数组的push方法
不修改putItem方法,通过Proxy包装静态cart数组拦截其push操作:
const func = (WalmartCart) => { const enhancedCart = []; const originalCart = WalmartCart.cart; // 用Proxy包装原cart数组,拦截push方法 WalmartCart.cart = new Proxy(originalCart, { get(target, prop) { // 拦截push方法,返回自定义包装函数 if (prop === 'push') { return function(item) { const enhancedItem = { ...item, 'some new data': 'new data' }; enhancedCart.push(enhancedItem); // 执行原数组的push操作,可选择传入原item或增强后的item return target.push(item); }; } // 其他数组方法保持原有逻辑 return Reflect.get(target, prop); } }); return enhancedCart; };
关键说明
- 两种方案都会创建独立的结果数组,后续每次调用
putItem时自动添加增强后的元素 - 使用对象展开语法创建新元素,避免修改传入的原始
item(若无需保护原item,也可直接给item添加字段,但不推荐) - 可根据需求选择是否修改原静态
cart中的元素(即调用原push时传入原item或增强后的item)
内容的提问来源于stack exchange,提问作者Kate Miller
相关产品推荐
相关产品推荐

