绑定有很多种情况,几乎所有在程序代码中用到的标识,都存有绑定的问题。最常见的例如变量:var aNum = 100;上述一句代码(的语法),对应着三个语义:①例如沟通中的“再重申一下我的主张”。
②例如沟通中的“我们换个角度来看这个问题”。
③例如沟通中的“给你画个草图如何”。
□有一个标识,记为aNum;□标识所指代的数据,其值是可变的(即,变量);□该数据当前值为100。
对于大多数语言来说,第二个语义是一项执行过程中的限制,亦即表明任何可以访问到aNum标识的代码都可以改变它的值。为了简便,我们暂不讨论这一个语义的绑定问题。但第一、三个语义所述的:□有标识aNum,其数据当前值为100就明显作用于我们的计算:如果数据无值,或值不确定,则我们无法进行后续的计算过程。所以aNum = 100在语义上的“值100”将在何时被绑定到标识aNum,就是一个相当重要的问题。以一个代码片段来看(相信我,这是实际可运行的代码)://代码1function process_part_one(){aNum = aNum * 2:var aNum = 100:5 }根据我们对这段代码的语法约定,第2、5行决定了代码片段中的标识符的生存周期①。但在这个生存周期中,aNum是何时有“值100”的含义的呢?对于这个问题,一些语言认为,表达“aNum变量具有初值100”这样的语义,应该是计算过程的前设,即对计算前提条件的声明。而声明并不是计算,因此声明语法与执行语法也应当分别对待。例如Pascal,就处理为这样的语法(在var部分声明,在begin...end部分执行)://代码2procedure process_part_one;varaNum = 100;beginaNum := aNum * 2:end;另一些语言则认为,声明语法可以理解为对执行环境的预置,也有执行含义,因此可以允许“即用即声明”,例如C。但是语义上,这是因“(需)即用”而进行的声明,不可能出现“已用”而未声明的情况。所以即使C语言,也会因为语义上无法解释,而判断上述代码1违例。
①如你所知的,这是一个函数。大多数语言的函数,都约定了其(形式上的)函数体内的标识符的生存周期。yipindushu.com
【还有一些语言认为:】
【var aNum】
是一个语义,它只表明标识aNum的存在,直到函数调用时才绑定另外一个语义:初始操作,即为函数内所有存在的标识进行初始化。在这样的认识下,“代码1”中的1 //代码32 function process_part_one(){var aNum4|}就具有了完整的语义。这个语义(即“初始操作”)与实际的计算机行为,是在把process_part_one()作为函数调用时,才进行绑定和实施的。其效果是:□在生命周期(代码3的2~4行,代码1的2~6行)中,记有一个标识aNum;且,□在该标识所处生命周期开始时,总会有一个初始化动作,使该标识具有一个初值:无值;且,□设整个计算环境中,无值是一种值,记为undefined。
你可能已经知道,这就是JavaScript的实现方法①。进一步地,除开上述代码在生命周期上的解释之外,代码1被理解为://代码4function process_part_one(){aNum = aNum * 2;// aNum有初值,记为undefinedaNum = 100:5}我们看到,代码1中的语法:var aNum = 100所具有的两个语义(本小节开始处的语义一、三)被分别绑定在函数调用开始和代码4的第4行;且一个标识的初值含义,总是被确定地约定为undefined。由此一来,上述代码1整体的语义就确定了。
【我们所谓的会“编程”是指:将我们的意图表达为计算系统的理解能力范围内的】
语义。而这种语义:①在JavaScript的实现中,这里被实现为闭包。当一个闭包被创建时,它的上下文自然被初始化,而非(显示地)进行一个赋以初值的操作。你可以认为闭包是一个内存块,它创造的时候就是一块空(full by Nil)的内存。
版权声明
本站素材均来源与互联网和网友投稿,欢迎学习分享
【节数以及对数据的性质的思考8:http://www.yipindushu.com/xuexifangfa/16540.html
推荐文章
09-13
1 【系统的基本组织方法与原理109-03
2 哲理句子真实点的文案09-03
3 哲理青春句子09-13
4 【节试错通常是无能的托辞409-13
5 【主要编程范式及其语言特性关系7