手机版

javascript用局部变量替换全局变量第1/2页

时间:2021-10-26 来源:互联网 编辑:宝哥软件园 浏览:

你为什么要这么做?有什么依据吗?如果不这样做,会带来多大的性能损失?本文将讨论这些问题的答案,从根本上了解哪些因素与变量的读写表现有关。版权声明本文翻译自尼古拉斯c扎卡斯于2009年2月10日在其个人网站上发布的《JavaScript Variable Performance》。是原文的唯一官方版本,本文为原作者(尼古拉斯c扎卡斯)授权的简体中文译本。译者(明达)在翻译的准确性上下了很大功夫,并承诺翻译的内容完全忠实于原文,但仍可能有遗漏和不足之处。请指正。翻译笔记的内容是非正式的,仅代表译者的个人观点。以下是原文的翻译:关于如何提高JavaScript的性能,最常听到的建议是尽可能使用局部变量而不是全局变量。在我九年的Web开发过程中,这个建议一直在我的耳朵里,从来没有被质疑过,这个建议的基础来自于JavaScript的作用域和标识符解析的方法。首先要明确函数在JavaScript中体现为对象,创建函数的过程其实就是创建对象的过程。每个函数对象都有一个名为[[作用域]]的内部属性,该属性包含创建函数时的作用域信息。实际上,[[范围]]属性对应于一个变量对象列表,列表中的对象可以从函数内部访问。比如我们设置一个全局函数A,A的[[作用域]]的内部属性只包含一个全局对象,而如果我们在A中创建新的函数B,B的[[作用域]]的属性包含两个对象,函数A的激活对象在前,全局对象在后。当一个函数被执行时,它会自动创建一个执行对象,同时绑定一个范围链。范围链将通过以下两个标识符解析步骤来建立。首先,将函数对象[[范围]]内部属性中的对象按顺序复制到范围链中。其次,在执行函数时,会创建一个新的Activation Object,它包含了这个、参数和局部变量(包括命名参数)的定义,这个Activation Object会放在作用域链的前面。在执行JavaScript代码的过程中,遇到标识符时,会根据标识符的名称在执行上下文的范围链中进行搜索。从作用域链的第一个对象(函数的Activation Object对象)开始,如果没有找到,搜索作用域链中的下一个对象,以此类推,直到找到标识符的定义。如果搜索后没有找到作用域中的最后一个对象,即全局对象,将引发错误,提示用户变量未定义。这是ECMA-262标准中描述的函数执行模型和标识符解析的过程。事实证明,大多数JavaScript引擎都是这样实现的。需要注意的是,ECMA-262并不需要这种结构,只是描述了这部分功能。了解了标识符解析的过程后,我们就能明白为什么局部变量的解析速度比其他范围的变量要快,主要是因为搜索过程大大缩短了。但是会有多快呢?为了回答这个问题,我模拟了一系列测试来测试变量在不同范围深度的性能。第一个测试是将最简单的值写入变量(这里使用的是文字值1)。结果如下图所示,很有意思:

从结果中不难看出,当标识符解析过程需要深度搜索时,会伴随着性能损失,性能损失的程度会随着标识符深度的增加而增加。不出所料,Internet Explorer的表现最差(但公平地说,IE 8仍有一些改进)。值得注意的是,这里也有一些例外。谷歌Chrome和最新的WebKit午夜版保持了访问变量的稳定时间,不会随着范围深度的增加而增加。当然,这应该归功于他们使用的下一代JavaScript引擎,V8和SquirrelFish。这些引擎在执行代码时进行了优化,显然,这些优化使访问变量比以前更快。Opera也表现不错,比IE、火狐和当前版本的Safari快很多,但比基于V8和Squirrelfish的浏览器慢。火狐3.1 Beta 2的性能有点出乎意料,执行局部变量的效率很高,但是随着范围内层数的增加,效率大大降低。需要注意的是,我这里使用的所有设置都是默认设置,这意味着火狐没有启动Trace功能。阅读下一页的全文。

版权声明:javascript用局部变量替换全局变量第1/2页是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。