`
魏祖清
  • 浏览: 180241 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

为什么尽量用局部变量代替全局变

    博客分类:
  • js
阅读更多
在如何提高JavaScript性能这个问题上,大家最常听到的建议应该就是尽量使用局部变量(local variables)来代替全局变量(global variables)。在我从事Web开发工作的九年时间里,这条建议始终萦绕在我的耳边,并且从来没有质疑过,而这条建议的基础,则来自于 JavaScript处理作用域(scoping)和标识符解析(identifier resolution)的方法。

首先我们要明确,函数在JavaScript中具体表现为对象,创建一个函数的过程,其实也就是创建一个对象的过程。每个函数对象都有一个叫做 [[Scope]]的内部属性,这个内部属性包含创建函数时的作用域信息。实际上,[[Scope]]属性对应的是一个对象(Variable Objects)列表,列表中的对象是可以从函数内部访问的。比如说我们建立一个全局函数A,那么A的[[Scope]]内部属性中只包含一个全局对象(Global Object),而如果我们在A中创建一个新的函数B,那么B的[[Scope]]属性中就包含两个对象,函数A的Activation Object对象在前面,全局对象(Global Object)排在后面。

当一个函数被执行的时候,会自动创建一个可以执行的对象(Execution Object),并同时绑定一个作用域链(Scope Chain)。作用域链会通过下面两个步骤来建立,用于进行标识符解析。

   1. 首先将函数对象[[Scope]]内部属性中的对象,按顺序复制到作用域链中。
   2. 其次,在函数执行时,会创建一个新的Activation Object对象,这个对象中包含了this、参数(arguments)、局部变量(包括命名的参数)的定义,这个Activation Object对象会被置于作用域链的最前面。

在执行JavaScript代码的过程中,当遇到一个标识符,就会根据标识符的名称,在执行上下文(Execution Context)的作用域链中进行搜索。从作用域链的第一个对象(该函数的Activation Object对象)开始,如果没有找到,就搜索作用域链中的下一个对象,如此往复,直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象,也就是全局对象(Global Object)以后也没有找到,则会抛出一个错误,提示用户该变量未定义(undefined)。这是在ECMA-262标准中描述的函数执行模型和标识符解析(Identifier Resolution)的过程,事实证明,大部分的JavaScript引擎确实也是这样实现的。需要注意的是,ECMA-262并没有强制要求采用这种结构,只是对这部分功能加以描述而已。


  所以: * 仔细检查函数中所有使用的变量,如果有一个变量不是当前作用域定义的,而且使用了不止一次,那么我们就应该把这个变量保存在局部变量中,而使用这个局部变量来进行读写操作。这样可以帮助我们将作用域外的变量的搜索深度减少到1.这对全局变量尤为重要,因为全局变量总是被放到作用域链的最后位置来搜索。
    * 避免使用with语句。因为它会修改执行上下文(Execution Context)的作用域链,在最前面添加一个对象(Variable Object)。这就意味着在执行with的过程中,实际上的局部变量都被移到作用域链上的第二个位置,这会带来性能上的损失。
    * 如果你确定一段代码肯定会抛出异常,那么就要避免使用try-catch,因为catch分支在作用域链上的处理方法和with是一样的。但try分支的代码是没有性能损失的,所以还是建议用try-catch来捕获那些不可预知的错误
分享到:
评论

相关推荐

    类变量、全局变量、实例变量, 多态、为什么ruby、ruby编码规范

    通常,推荐使用局部变量和实例/类变量来代替全局变量。 ```ruby $global_var = "Greetings, Global!" puts $global_var # 输出 "Greetings, Global!" ``` 三、实例变量 实例变量以`@`开头,它们是对象的私有属性...

    配合 CGV 类工作的全局变量 - MetaTrader 5程序库.zip

    4. 考虑到代码的可读性和可扩展性,应尽量减少全局变量的数量,使用局部变量和对象属性代替。 综上所述,这个资料包提供了一个实用的方法来管理和操作MetaTrader 5中的全局变量,通过使用CGV类可以提高代码质量,...

    C#程序变量统一管理例子

    2. 尽量避免全局变量:全局变量可能导致意外的副作用,尽量使用局部变量和类成员代替。如果必须使用全局变量,确保它们有适当的封装和访问修饰符。 3. 使用const和readonly:对于不会改变的常量,使用`const`关键字...

    基于嵌入式系统中c语言代码运行效率探析.pdf

    例如,在函数内部使用局部变量counts代替全局变量count,可以显著减少对存储器的访问次数,避免每次都需要将变量从存储器中加载到寄存器,再写回存储器。 再次,针对参数传递的效率问题,文章指出,在C语言与汇编...

    53个编程技巧提高PHP开发效率.doc

    9. 递增一个局部变量要比递增一个全局变量慢 2 倍。 10. 递增一个对象属性要比递增一个局部变量慢 3 倍。 文件和路径 11. include 文件时尽量使用绝对路径,因为它避免了 PHP 去 include_path 里查找文件的速度,...

    Java编程中“为了性能”尽量要做到的一些地方

    尽量使用局部变量 局部变量存储在栈中,访问速度快于堆中的对象。因此,对于那些生命周期较短、不需要长时间存在的变量,优先考虑使用局部变量。 #### 6. 慎重处理包装类型和基本类型的使用场景 基本类型和包装...

    如何使用C语言来编写MSP430的高质量代码

    3. **局部变量的使用**:为了更好地利用CPU寄存器,应尽量使用局部变量而非全局变量。局部变量更容易被编译器优化。 4. **模块内变量声明为static**:对于只在特定模块内部使用的变量,应该声明为 `static` 类型。...

    50点提高PHP编程效率 引入缓存提升性能

    19. 全局变量与局部变量:递增全局变量比递增局部变量慢约2倍。 20. 对象属性操作:递增对象属性比递增局部变量慢3倍。 21. 未定义变量:递增未定义的局部变量比递增已定义的局部变量慢9到10倍。 22. 未使用的...

    Bootstrap Table 搜索框和查询功能

    因此,我们需要尽量减少全局变量的声明,使用局部变量来代替全局变量。在上面的代码中,我们可以看到作者是如何使用局部变量来缓存全局变量的。 缓存 DOM 节点查找结果 在 JS 代码中,我们经常需要查找 DOM 节点,...

    程序优化方法

    - 避免使用局部变量的地址,因为这可能导致访问速度变慢。 8. 结构体的安排: - 小型成员放在结构体前面,大型成员放在后面,以优化内存对齐。 - 避免过大的结构体,使用层次化的子结构体代替。 - 为 API ...

    基于KeilC51编译器的程序优化设计.pdf

    因此,在不影响程序功能的前提下,应尽量使用局部变量而非全局变量。 ### 4. 减少函数调用 频繁的函数调用会增加程序的开销,包括参数传递、保存现场等操作。因此,对于简单的操作,应尽量减少函数调用次数,可以...

    8位单片机的程序优化11条

    #### 五、用局部变量代替全局变量 定义局部变量比全局变量更为高效。这是因为编译器将局部变量存储在内部存储区中,而全局变量则存储在外部存储区,后者访问速度较慢。此外,过度依赖全局变量可能会导致程序维护...

    C语言可重入函数及函数编写规范

    - **使用本地数据保护全局数据**:如果需要使用全局数据,可重入函数应该使用局部变量来复制这些数据,或者通过信号量等方式来保护全局数据,确保数据的一致性和完整性。 - **避免调用不可重入函数**:可重入函数不...

    Javascript 开发规范

    总结,JavaScript开发规范是提升代码质量的关键,包括但不限于文件编码、变量声明规则、使用局部变量代替全局变量、匿名函数的格式等。遵循这些规范,能确保代码更加整洁、易于理解,同时降低维护成本。

    PHPER代码优化建议

    21. 全局变量与局部变量:递增全局变量比递增局部变量慢约2倍。 22. 对象属性与局部变量:递增对象属性比递增局部变量慢3倍。 23. 预定义变量:递增未定义的局部变量比递增预定义的局部变量慢9到10倍。 24. 未...

    54点提高PHP编程效率!

    递增局部变量通常比递增全局变量更快,且接近于函数内部变量的操作速度。 #### 19. 全局变量与局部变量的递增 递增全局变量的速度大约是递增局部变量的两倍。 #### 20. 对象属性与局部变量的递增 递增对象属性...

    提高PHP开发效率的技巧_.docx

    19. **全局变量与局部变量**:递增全局变量比递增局部变量慢大约两倍。 20. **对象属性操作**:递增对象属性比递增局部变量慢三倍。 21. **未定义变量**:递增未定义的局部变量比递增已定义的局部变量慢9到10倍。 ...

    优化PHP代码的40条建议

    24. 定义但未使用的局部变量:即使未在函数中使用,定义局部变量也会降低性能,因为 PHP 会检查是否有同名的全局变量。 25. 方法调用的影响:方法调用的性能与类中方法的数量关系不大,但与具体的调用方式有关。 ...

Global site tag (gtag.js) - Google Analytics