(转)递归函数提前声明变量分析
By
admin
at 2021-02-07 • 0人收藏 • 839人看过
感谢: 圣地 分享
import console; /* 背景: 赋值语句方式定义递归函数时函数体中调用函数名本身必须将函数名变量的声明提到定义函数前 这样递归函数正常运行,如不提前会导致函数体内的函数名变量为 Null 无法正常运行。 */ var funcBad/*(2)*/ = function(){ console.log("函数体内 funcBad 的指针:", type(funcBad) ,funcBad/*(1)*/ ) } funcBad() console.log("函数体外 funcBad 的指针:",type(funcBad), funcBad ) /***** funcBad分析: 创建函数的过程: 1) 先执行右值创建函数 2) 检查函数体是否有不符合语法规则的语句如有提示,这里只检查标识符是否合法 3) 发现函数体有一个未声明变量 funcBad/*(1)*/ 将其变量地址记为 Null 4) 执行左值声明 funcBad 变量 5) 将右值整个函数体在内存中创建的函数指针0x456赋值给 funcBad/*(2)变量地址0x123*/ 此时,funcBad/*(2)0x123*/值为一个函数指针0x456; funcBad/*(1)*/ 变量地址 Null var funcBad/*(2)0x123: 0x456*/ = function()0x456{ console.log("函数体内 funcBad 的指针:", type(funcBad) ,funcBad/*(1)Null*/ ) } 调用 funcBad(),结果函数体 funcBad/*(1)*/ 输出 Null *****/ var funcOK/*(4)*/ = 123;//或 = null; 也可以正常运行 var funcOK/*(3)*/; funcOK/*(2)*/ = function(){ console.log("函数体内 funcOK 的指针:", type(funcOK) ,funcOK/*(1)*/ ) } funcOK() console.log("函数体外 funcOK 的指针:",type(funcOK), funcOK ) /***** funcOK分析: 创建函数的过程: 1) 提前声明变量 funcOK/*(3)*/ 变量地址0x123; 2) 先执行右值创建函数 3) 检查函数体是否有不符合语法规则的语句如有提示,这里只检查标识符是否合法 4) 此时函数体中 funcOK/*(1)*/ 因为已声明所以将其变量地址记为 0x123 5) 将右值整个函数体在内存中创建并分配指针 0x456 后赋值给左值 funcOK/*(2)0x123*/ 6) 函数体中funcOK/*(1)0x123*/ 同5)联动,其变量的值同时改为函数指针 0x456 此时, funcOK/*(2)*0x123:值为:0x456/ = function()0x456{ console.log("函数体内 func 的指针:", type(funcOK) ,funcOK/*(1)*0x123:值为0x456/ ) } 所以,提前声明变量的方法可以让这种类似递归调用的函数正常运行。 疑问解答: 为什么 var funcOK/*(4)*/ = 123; 时也可以正常运行? 这里声明的关键是为 funcOK 分配一个变量地址后续可以正常运行就是用到了个地址, 因为是动态语言变量类型都可以根据值来改变, 在第 5) 步时重新为这个funcOK/*(2)0x123*/变量赋值函数指针0x456所以前面声明给的 Null 也可以。 *****/ console.pause(true)
登录后方可回帖