(转)递归函数提前声明变量分析

By admin at 2021-02-07 • 0人收藏 • 329人看过

感谢: 圣地 分享

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)


登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前在学aardio+halcon机器视觉.
加入本站专享群:783804676
AARDIO语言QQ大群:70517368
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
苏扬博客:苏扬博客
C大Aardio论坛:Aar爱好者论坛
简码教程网:简码编程
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
aardio在线手册Aardio在线手册

赞助商:才仁机械
下载站:
非凡软件站
Loading...