函数柯里化正确实现:修复addNum函数调用次数统计失效及TypeError错误
解决addNum函数链式调用统计次数的问题
首先,咱们先拆解下你现有代码的两个核心问题:
问题1:无法累计调用次数
你每次调用addNum时,都会重新声明let sum = 0,相当于每次调用都是一个全新的局部变量,根本没法累计之前的调用次数——哪怕你调用十次,每次的sum都是从0开始加1,永远只能得到1。
问题2:链式调用时找不到getInnerNum方法
你的addNum返回的是一个匿名函数,而getInnerNum是挂载在addNum函数本身的属性上。当你写addNum().getInnerNum()时,你其实是在调用返回的匿名函数上找getInnerNum方法,但这个匿名函数根本没有这个属性,自然会抛出类型错误。
解决方案1:利用闭包实现私有计数(推荐)
这种方式会把计数变量sum放在闭包里,外部无法直接修改,更安全,同时支持链式调用:
const addNum = (function() { // 闭包保存私有计数,不会被外部修改 let sum = 0; // 定义核心调用函数 function callable() { sum += 1; // 返回自身,实现链式调用 return callable; } // 挂载获取计数的方法 callable.getInnerNum = function() { return sum; }; return callable; })();
测试一下预期效果:
addNum().getInnerNum()→ 返回1addNum()()().getInnerNum()→ 返回3addNum()()()()().getInnerNum()→ 返回5
为什么这样可行?
- 闭包里的
sum只会初始化一次,每次调用callable(也就是addNum)都会累加这个值; - 每次调用后返回
callable自身,所以链式调用的每一步都是在调用同一个函数,自然能持续累加; getInnerNum直接挂载在callable上,不管是直接调用addNum还是链式调用返回的函数,都能访问到这个方法。
解决方案2:利用函数静态属性实现计数
如果你不需要私有性,只想快速实现功能,可以直接把计数存在addNum的静态属性上:
function addNum() { // 累加静态属性里的计数 addNum.sum += 1; // 返回自身支持链式调用 return addNum; } // 初始化计数 addNum.sum = 0; // 挂载获取方法 addNum.getInnerNum = function() { return this.sum; };
同样能实现你要的效果,缺点是外部可以直接修改addNum.sum来篡改计数,比如addNum.sum = 100会直接影响后续统计。
内容的提问来源于stack exchange,提问作者rick1
相关产品推荐
相关产品推荐

