ORIGIN全文地址:JavaScript专项算法题(3):闭包推荐:编程鼠标·电竞鼠标闭包、作用域和运行上下文挑战1 createFunction问题:构建createFunction函数,用于创建和返回函数。当被创建的函数被调用时,它会打印“hello"。题解:// CHALLENGE 1functioncreateFunction(){constinnerFunction=()={console.log("hello");}returninnerFunction;}/*** Uncomment these to check your work! ***/constfunction1=createFunction();function1();// = should console.log('hello');挑战2 createFunctionPrinter问题:构建接受一个输入值作为参数的createFunctionPrinter函数,用于创建和返回一个特定函数。当特定函数被调用时,其应该打印特定函数被创建时输入createFunctionPrinter中的值。题解:// CHALLENGE 2functioncreateFunctionPrinter(input){constinnerValue=input;constinnerFunction=()={console.log(innerValue);}returninnerFunction;}/*** Uncomment these to check your work! ***/constprintSample=createFunctionPrinter('sample');printSample();// = should console.log('sample');constprintHello=createFunctionPrinter('hello');printHello();// = should console.log('hello');挑战3 addByX问题:观察下面outer函数的实现代码。注意其会返回一个函数而且那个函数使用了不在其作用域的变量。尝试推断一下运行outer函数得到的输出值,然后构建addByX函数,其会返回一个接受一个输入值作为参数并与x相加的函数。代码:// CHALLENGE 3functionouter(){letcounter=0;// this variable is outside incrementCounter's scopefunctionincrementCounter(){counter++;console.log('counter',counter);}returnincrementCounter;}constwillCounter=outer();constjasCounter=outer();// Uncomment each of these lines one by one.// Before your do, guess what will be logged from each function call./*** Uncomment these to check your work! ***/willCounter();willCounter();willCounter();jasCounter();willCounter();functionaddByX(x){letbackpackValue=x;constinnerFunction=(el)={returnbackpackValue+el;}returninnerFunction;}/*** Uncomment these to check your work! ***/constaddByTwo=addByX(2);console.log(addByTwo(1));// = should return 3console.log(addByTwo(2));// = should return 4console.log(addByTwo(3));// = should return 5constaddByThree=addByX(3);console.log(addByThree(1));// = should return 4console.log(addByThree(2));// = should return 5constaddByFour=addByX(4);console.log(addByFour(4));// = should return 8console.log(addByFour(5));// = should return 9挑战4 once问题:构建once函数,接受参数为一个回调函数并返回一个特定函数。当特定函数被第一次调用时,其会调用回调函数并返回输出值。如果其不是被第一次调用,则特定函数仅仅返回第一次调用时得到的回调函数返回值,而不是再次运行回调函数。题解:// CHALLENGE 4functiononce(func){letcounter=0;letinnerValue=0;constinnerFunction=(el)={counter++;if(counter==1){innerValue=func(el);returninnerValue;}else{returninnerValue;}}returninnerFunction;}/*** Uncomment these to check your work! ***/constonceFunc=once(addByTwo);console.log(onceFunc(4));// = should log 6console.log(onceFunc(10));// = should log 6console.log(onceFunc(9001));// = should log 6挑战5 after问题:构建after函数,接受一个数字n和一个回调函数作为参数。回调函数需要在通过after构建的函数运行第n次时才被运行。题解:// CHALLENGE 5functionafter(count,func){letcounter=count;constinnerFunction=()={counter--;if(counter==0){func();}}returninnerFunction;}/*** Uncomment these to check your work! ***/constcalled=function(){console.log('hello')};constafterCalled=after(3,called);afterCalled();// = nothing is printedafterCalled();// = nothing is printedafterCalled();// = 'hello' is printed挑战6 delay问题:构建delay函数,接受一个回调函数作为第一个参数,一个数值n(单位为毫秒)作为第二个参数。delay函数被调用后,须经n毫秒后才运行回调函数。任何其他赋给特定函数的参数会在n毫秒后被回调函数使用。提示:研究setTimeout();题解:// CHALLENGE 6functiondelay(func,wa