当前位置: 首页 > Web前端 > JavaScript

《javascript高级程序设计》学习笔记-10.12-10.13,递归

时间:2023-03-27 11:38:47 JavaScript

关注前端小鱼,阅读更多原创技术文章相关代码→10.12递归递归函数就是通过名字调用自己的函数functionfactorial(num){if(num<=1){return1}else{returnnum*factorial(num-1)}}函数逻辑和函数名是耦合的,所以将递归函数赋值给其他变量,去掉原函数名和函数的关系后,会报错letanotherFactorial=factorial//访问指针factorial=null//切断阶乘和函数之间的联系console.log(anotherFactorial(4))//TypeError:factorialisnotafunctionusearguments.calleedecouple(arguments.calleepointstopointer到参数所在的函数)functionfactorial2(num){if(num<=1){return1}else{returnnum*arguments.callee(num-1)}}letanotherFactorial2=factorial2//访问指针factorial2=null//切断bee之间的连接nfactorialandthefunctionconsole.log(anotherFactorial2(4))//24、arguments.callee指向anotherFactorial2在严格模式下,argumengts.callee无法访问(会报错),使用具名函数表达式来达到目的让factorial3=functionf(num){if(num<=1){return1}else{returnnum*f(num-1)//无论赋给哪个变量,表达式f都不会改变}}letanotherFactorial3=factorial3factorial3=nullconsole.log(另一个Factorial3(4))//2410.13尾调用优化ES6加入了非常适合尾调用的内存管理优化机制,即外层函数的返回值是内层函数的返回值functionouterFunction(){returninnerFunction()//tailcall}在ES6优化之前,这个例子在内存中会进行如下操作(每次调用嵌套函数都会额外增加一个栈帧):执行到outerFunction函数体,第一个栈帧会被压入栈执行outerFunction函数体return语句,计算返回值,先计算innerFunction并执行到innerFunction函数体,第二个栈帧被压入栈执行innerFunction函数体,计算返回值并将返回值传回outerFunction,然后outerFunction返回值弹出栈帧ES6优化出来sidethestack,本例在内存中会进行如下操作(无论调用多少次嵌套函数,都只有一个栈帧):执行到outerFunction函数体,第一个栈帧压入栈执行outerFunction函数体到return语句,计算返回值首先要计算innerFunction,因为innerFunction的返回值也是outerFunction的返回值,所以引擎发现第一个栈帧可以pop出将outerFunction的栈和栈帧出栈到innerFunction函数体,第二个栈帧压入栈执行innerFunction函数体,计算返回值并弹出innerFunction的栈帧出栈ES6尾调用优化的关键:如果函数的逻辑允许基于尾调用销毁,那么引擎会有这么多10.13.1tail调用优化的条件需要判断外部栈帧确实不需要存在:外部代码需要以严格模式执行。非严格模式允许的f.arguments和f.caller都将引用外部函数的堆栈帧。外部函数的返回值是对尾调用函数调用后的,尾调用函数返回后不需要执行额外的逻辑。尾调用函数不是引用外部函数范围内的自由变量的闭包;('usestrict')functionouterFunction(){innerFunction()//无优化,尾调用不返回}functionouterFunction(){letinnerFunctionResult=innerFucntion()returnrninnerFunctionResult()//没有优化,尾调用不直接返回}functionouterFunction(){returninnerFunction().toString()//没有优化,尾调用返回后必须转为字符串(附加逻辑)}functionouterFunction(){letfoo='bar'functioninnerFunction(){returnfoo}returninnerFunction()//没有优化,尾调用是闭包}functionouterFunction(a,b){innerFunction(a+b)//是优化,在栈帧销毁前进行参数计算}functionouterFunction(a,b){if(a