不使用ES6语法编写memoize函数:无扩展/剩余运算符实现多参数支持
不依赖ES6扩展/剩余运算符的memoize函数实现
先提下你原ES6代码里的小问题:else块里先把func(...args)的结果存进缓存,之后又重新调用一次func(...args)返回,这等于白做了缓存——每次都会执行两次原函数,得改成存完直接返回缓存结果才行。
回到你的需求,在ES5环境里,我们可以用arguments对象和apply方法替代扩展/剩余运算符的功能,实现支持任意参数的memoize函数:
function memoize(func) { var cache = {}; return function() { // 把arguments转成数组后序列化,生成唯一缓存键 var argsKey = JSON.stringify(Array.prototype.slice.call(arguments)); if (argsKey in cache) { return cache[argsKey]; } // 用apply把所有参数传给原函数,避免重复执行 var result = func.apply(null, arguments); cache[argsKey] = result; return result; }; };
关键细节说明:
- 获取任意参数:在普通函数里,
arguments是类数组对象,包含调用时传入的所有参数,用Array.prototype.slice.call(arguments)可以把它转成真正的数组,方便后续处理。 - 生成缓存键:用
JSON.stringify把参数数组转成字符串,只要参数的结构和值完全一致,就能生成相同的键,保证缓存正确性。如果参数里有函数、Symbol这类无法序列化的类型,这个方法会有局限,但原ES6版本也存在同样问题。 - 调用原函数:用
func.apply(null, arguments)替代func(...args),apply方法会自动把arguments里的每个元素作为单独参数传递给原函数,实现和扩展运算符一样的效果。 - 修正缓存逻辑:只执行一次原函数,把结果存入缓存后直接返回,避免不必要的重复计算。
内容的提问来源于stack exchange,提问作者M S
相关产品推荐
相关产品推荐

