大家好,我是前端西瓜哥,今天我们来做一道简单的前端面试题。在JavaScript中实现一次函数,要求传入的函数只能执行一次。并且在第二次及以后调用时,还是会返回第一次执行时的值。效果要求如下:constaddOnce=once(function(a,b){returna+b;});addOnce(1,2);//3addOnce(1,2999);//关于闭包的概念,这里还涉及到3个想法和实现。什么是闭包?闭包是一种允许一个函数访问另一个函数内的变量(或相关环境)的技术。一种常见的方法是调用一个函数a,它返回一个新创建的函数b。得到的效果是:新函数b可以访问a中声明的变量。once函数将使用闭包的力量来返回绑定到作用域的新函数。我们先来看实现。functiononce(fn){letret;//使用returnfunction(...args)缓存结果{if(!fn)returnret;ret=fn(...参数);fn=未定义;//表示已经执行一次returnret;}}使用闭包,我们返回的新函数有两个可以访问的“私有”变量:传入的fn函数;额外声明的ret变量,用于缓存调用返回的新函数时的结果,我们先将参数传递给fn,获取返回值缓存在ret中。然后将fn设置为undefined来标记已经执行了一次,最后返回ret。下次调用时,判断fn为falsy,直接返回缓存的ret。另外,貌似可以给fn加个类型检查:typeoffn==='function'向面试官表达你代码的健壮性。还有一个比较有意思的地方:如果返回一个对象,那么多次调用的返回值其实都指向同一个对象。如果希望每次返回的对象都是一个新的对象,可以考虑返回一个复制的对象(如果可以复制的话)。onceattheend的实现并不复杂。只要用闭包保存一个缓存的返回值和是否执行过的状态,就可以控制函数的执行方向。
