Javascript域与域链的深入分析

Javascript域与域链的深入分析
范围是Javascript最重要的概念之一。为了更好地学习Javascript,您需要了解Javascript范围和动作链的工作原理。本文简要介绍了Javascript范围和范围链,希望能帮助您了解更多关于Javascript的知识。

Javascript的范围

任何编程语言都有范围的概念。简单地说,范围是变量和函数的访问范围,也就是说,范围控制变量和函数的可见性和生命周期。在Javascript中,变量的作用范围有两种全局和局部作用域。

1。全球行动范围(全球范围)

可以在代码中任何地方访问的对象都具有全局范围,一般情况下,几个案例具有全局范围:

(1)外部函数定义的最外层函数和变量具有全局作用域,例如:
复制代码代码如下所示:
VaR的作者名字=溪山;
函数doSomething(){
无功blogname = ;
功能innersay(){
警报(blogname);
}
InnerSay();
}
警报(作者名字); / /山的溪流边
警报(blogname); / /脚本错误
(做某事); / /
(innersay) / /脚本错误

(2)定义结束时的所有变量都自动声明为全局范围,如:
复制代码代码如下所示:
函数doSomething(){
VaR的作者名字=溪山;
blogname = ;
警报(作者名字);
}
Alert (blogName); / /
警报(作者名字); / /脚本错误

变blogname具有全局范围,和作者名字不能被外界访问的功能。

(3)所有窗口对象的属性都具有全局范围。

一般来说,内置的窗口对象的属性具有全局范围,如window.name,window.location,window.top等等。

2。地方行动范围(地方范围)

在全球范围内,一般在局部范围内只有固定的代码片段可以访问最常用的功能,如内部,所有在一些地方也会看到范围为一个范围,功能,例如,下面的代码在blogname和innersay功能具有局部范围。
复制代码代码如下所示:
函数doSomething(){
无功blogname = ;
功能innersay(){
警报(blogname);
}
InnerSay();
}
警报(blogname); / /脚本错误
(innersay); / /脚本错误

范围链(范围链)

在Javascript中,函数也是对象,而事实上,所有的Javascript是一个对象,函数对象,其他物体一样,具有可访问的代码和一系列是由Javascript引擎只访问内部属性。它的一个内在特性是{ } { }的范围,由ECMA-262第三版定义。内部属性包含函数创建作用域中的一组对象。这个集合称为函数的范围链,它决定函数可以访问哪些数据。

当一个函数被创建时,它的作用域链由可以在创建的函数的范围内访问的数据对象填充:
复制代码代码如下所示:
添加函数(num1,num2){
VaR和= num1和num2;
收起回复;
}

创建函数添加时,它将在范围链中填充一个全局对象。全局对象包含所有全局变量,如下图所示(注:图片只列出所有变量的一部分)。
函数添加的范围将在执行时使用:
复制代码代码如下所示:
无功总=加(5,10);

当执行此函数时,创建一个称为执行上下文的内部对象,运行时上下文在执行该函数时定义环境。每个运行时上下文都有自己的范围链,用于标识符解析。当运行时上下文被创建时,它的作用域链被初始化为当前运行函数的{ } }所包含的对象。

这些值被复制到运行时环境在他们的顺序出现在函数的作用域链。他们一起形成一个新的对象,称为主动对象(活动对象),该对象包含所有的局部变量,命名参数,这个参数的设置和功能,那么对象将被推到的范围产业链的前端,当执行环境被破坏,将会破坏活动对象。新的作用域链如下图所示:
在函数执行过程中,遇到了不可变的,都会经历一个标识符解析过程确定获取和存储数据。从作用域链头的过程,即从活动的目标开始搜索发现同一名称的标识符,如果使用此标识符对应的变量,如果没有找到继续搜索范围链上的下一个对象,如果搜索没有找到所有的对象标识符是未定义的。在函数执行过程中,每个标识符必须接受这样的搜索过程。

范围链和代码优化

从作用域链的结构,可以看出更深的标识符,慢的读写速度将在运行时上下文的作用域链。如上图所示,因为全局变量总是存在于运行时上下文的作用域链的末端,这是最慢的发现全局变量分析。所以,当你写代码,你应该尝试使用尽可能少的全局变量和局部变量,使用尽可能多的。一个好的经验法则是,如果在一个交叉的对象范围是指一个以上的时间,它是存储在一个局部变量一然后再次使用。例如,下面的代码:
复制代码代码如下所示:
功能换色(){

document.getelementbyid(btnchange)。Onclick =函数(){

document.getelementbyid(targetcanvas)。风格。背景颜色为红色;

};

}

这个函数引用两个全局变量文档,即发现变量必须遍历整个范围链,直到最终在全局对象中找到:
复制代码代码如下所示:
功能换色(){

文档;

doc.getelementbyid(btnchange)。Onclick =函数(){

doc.getelementbyid(targetcanvas)。风格。背景颜色为红色;

};

}

这个代码比较简单。重写后,它不会表现出巨大的性能改进。但是,如果有大量的全局变量被反复访问,重写代码的性能将得到显著改善。

改变行动的链条

一个函数的执行上下文中执行时每次都是独一无二的,所以调用同一个函数多次会造成多个运行时环境,并执行上下文将被摧毁,当函数被执行。每个运行时上下文与一个作用域链有关。在一般情况下,在运行时上下文,它的作用域链是由语句与语句只影响

带语句是对象避免编写重复代码的一种快捷方式
复制代码代码如下所示:
功能initui(){

用(文档){

var =主体,

链接= getElementsByTagName(),

我= 0,

links.length len =;

当(i){

更新(链接{ + });

}

getElementById(btninit)。Onclick =函数(){

DoSomething();

};

}

}

这里使用宽度语句避免多次写入文档,它看起来更高效,实际上会产生性能问题。

当代码运行的语句,在运行时上下文的作用域链是暂时的改变。一个新的变量创建对象,其中包含由参数指定的对象的所有属性,该对象将被推入作用域链的头,这意味着所有的函数的局部变量在第二范围链对象,所以访问成本较高。如下图:

因此,您应该避免在程序中使用带语句,在这种情况下,可以简单地将文档存储在局部变量中,从而提高性能。

另一个catch语句将改变范围链try-catch语句。在try代码块中发生错误时,执行过程会跳到catch语句,然后将异常对象为可变对象放在范围的头。在catch代码块,所有的功能局部变量将被放置在第二范围链对象。示例代码:
复制代码代码如下所示:
尝试{

DoSomething();

} catch(前){

警报(ex.message); / /范围链的改变

}

注意,一旦catch语句完成时,作用域链返回到以前的状态。try-catch语句在代码的调试和异常处理是非常有用的,所以这是不推荐的,它是完全可以避免的。你可以减少catch语句的代码优化性能的影响是一个很好的模型来代表。一个错误的功能,如:
复制代码代码如下所示:
尝试{

DoSomething();

} catch(前){

HandleError(前); / /委托处理器方法

}

优化代码,handleError方法是唯一的代码,在catch子句执行。此功能接收到异常对象作为参数,这样你可以更灵活地处理错误和统一。因为只有一个语句被执行,没有获得一个局部变量,作用域链的临时变化不会影响代码的性能。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部