作用域全局作用域局部作用域链执行上下文活动对象闭包优化JavaScript中出现了一个以前没有学过的概念——闭包。什么是结束?从表面上看,一个封闭的包与范围有关。因此,在讨论闭包之前,我们先来讨论范围。范围一般来说,一段程序代码中使用的变量和函数并不总是可用的,它的可用范围被定义为范围。范围的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名称冲突。全局作用域(Global Scope)可以在代码中任何地方访问的对象都具有全局作用域,以下情况具有全局作用域:1。最外层函数和最外层函数外定义的变量具有全局作用域,例如,复制的代码如下: var OutLook=' var OutLook ';function OutFunction(){ var name=' var inner ';函数InSideFunction(){ alert(name);} InSideFunction();} alert(OutLook);//正确的警报(名称);//错误OutFunction();//更正inSideFunction() //错误2。没有定义直接赋值的变量被自动声明为具有全局作用域。例如,复制代码如下: blogName='CSDN李达' 3。窗口对象的所有属性都具有全局范围。例如,窗口对象的内置属性具有全局范围。例如,复制窗口.名称、窗口.位置和窗口.顶部等本地范围的代码如下function OutFunction(){ var name=' inner name ';function InFunction(){ alert(name);} InFunction();} alert(名称);//错误InFunction();//error /span作用域链)JavaScript,JavaScript中的一切都是对象,包括函数。像其他对象一样,函数具有可以通过代码访问的属性和一系列只能由JavaScript引擎访问的内部属性。内部属性之一是作用域,它包含创建函数的作用域中的对象集合,称为函数的作用域链,它决定函数可以访问哪些数据。当一个函数被创建时,它的作用域链将在创建该函数的作用域中被可访问的数据对象填充。例如,复制代码如下:函数add (num1,num 2){ var sum=num 1 num 2;返回总和;}创建函数add时,其作用域链将填充一个全局对象,该对象包含所有全局变量,如下图所示(注:图片仅举例说明了所有变量中的一部分):。
因此,函数的范围链是在创建函数时创建的。执行上下文函数添加的范围将在执行过程中使用。例如,复制代码如下:VARTTAL=ADD (5,10);执行add函数时,JavaScript将创建一个Execute上下文,其中包含add函数运行时所需的所有信息。执行上下文也有自己的范围链。当函数运行时,JavaScript引擎将首先从add函数的作用域链中初始化执行上下文的作用域链。活动对象,然后JavaScript引擎将创建一个活动对象。这些值根据它们在函数中出现的顺序被复制到运行时上下文的范围链中,它们一起形成了一个新的对象——“激活对象”。这个对象包含函数运行时的所有局部变量、参数和这个变量。该对象将被推到范围链的前面。当运行时上下文被销毁时,活动对象将被销毁。新的范围链如下所示:。
执行上下文是一个动态概念,在函数运行时创建,活动对象也是一个动态概念,由执行上下文的范围链引用。可以得出结论,执行上下文和活动对象都是动态概念,执行上下文的范围链由函数范围链初始化。在函数执行的过程中,每次遇到一个变量,它都会搜索在哪里获取和存储数据。这个过程从作用域链的头开始,也就是从活动对象开始,寻找同名的标识符。如果找到,它将使用对应于该标识符的变量。如果没有找到,它将继续搜索范围链中的下一个对象。如果搜索后没有找到所有对象,则认为该标识符未定义。在函数执行的过程中,每个标识符都会经历这样的搜索过程。闭包首先看一个例子,javascript代码:复制代码如下: script type=' text/JavaScript '函数new load(){//为(var i=1)创建一个新的页面加载事件;I=3;I){ var anchor=document . getelementbyid(' anchor ' I);//找到每一个主播主播。onclick=function(){//为锚点添加一个click事件提醒('您单击了锚点' I );//给出点击响应} } } window.onload=newLoad//将新load事件赋给页面加载/脚本的前台代码:复制的代码如下: body a id=' anchor 1 ' href=' # ' anchor 1/ABR/a id=' anchor 2 ' href=' # ' anchor 2/ABR/a id=' anchor 3 ' href=' #。主播3/ABR//跑体结果:无论点击哪个主播,主播4总会弹出,但我们根本没有主播4:(9502 . 163.com)。
当我们加载页面时,javascript中的newLoad函数已经运行完毕。从它的循环中,我们可以看到锚点被赋予了一个值4。但是根据以前的编程经验,局部变量在使用后会被破坏,而anchor不会。显然,这里的JavaScript采用了另一种方式。闭包实际上是JavaScript中的一个函数,它是在函数运行时创建的。当执行上述函数时,将创建一个闭包,这个闭包将引用newLoad范围内的锚点。我们来看看JavaScript是如何实现闭包的:在执行newLoad函数时,JavaScript引擎会创建newLoad函数执行上下文的范围链,其中包含newLoad执行过程中的活动对象,同时JavaScript引擎也会创建一个闭包。闭包的作用域链也会引用newload的活动对象,所以在执行newload的时候,虽然它的执行上下文和活动对象已经释放了锚点,但是闭包还是引用了newload的活动对象,所以点击会显示“你点击了anchor4”。运营期如图:。
闭包优化既然闭包有意想不到的结果,我们就需要对其进行优化。优化后的javascript(其他不变):复制的代码如下: script type=' text/JavaScript '函数new load(){//event for new page load(var I=1;I=3;I){ var anchor=document . getelementbyid(' anchor ' I);//找到每个主播听众(主播,我);//监听器函数}}函数监听器(anchor,I) {anchor。onclick=function(){//为锚点添加一个click事件提醒('您单击了锚点' I );//给出点击响应} } window.onload=newLoad//为页面加载/脚本运行结果分配newload事件:提示对应的提示信息。
结果:优化的结果是我们将声明的变量与点击事件分开。用上面解释的作用域链解释:加载页面时,应该先执行监听器函数,但是监听器函数需要锚点变量,在监听器函数的作用域链中找不到,所以会进入作用域链的下一级,也就是在newLoad中找到锚点。因为已经在监听器中确定了哪个锚点点击了哪个提示信息,所以只需要在newload中找到对应的锚点,不会等待循环完成生成anchor4。因为你接触javascript的时间很短,请改正你的错误。