[翻译]High Performance JavaScript(008)

Nested Members  嵌套成员

 

    Since object members may contain other members, it's not uncommon to see patterns such as window.location.href in JavaScript code. These nested members cause the JavaScript engine to go through the object member resolution process each time a dot is encountered. Figure 2-12 shows the relationship between object member depth and time to access.

    由于对象成员可能包含其它成员,例如不太常见的写法window.location.href这种模式。每遇到一个点号,JavaScript引擎就要在对象成员上执行一次解析过程。图2-12显示出对象成员深度与访问时间的关系。

Figure 2-12. Access time related to property depth

图2-12  访问时间与属性深度的关系

 

    It should come as no surprise, then, that the deeper the nested member, the slower the data is accessed. Evaluating location.href is always faster than window.location.href, which is faster than window.location.href.toString(). If these properties aren't on the object instances, then member resolution will take longer as the prototype chain is searched at each point.

    结果并不奇怪,成员嵌套越深,访问速度越慢。location.href总是快于window.location.href,而后者也要比window.location.href.toString()更快。如果这些属性不是对象的实例属性,那么成员解析还要在每个点上搜索原形链,这将需要更长时间。

 

Caching Object Member Values  缓存对象成员的值

 

    With all of the performance issues related to object members, it's easy to believe that they should be avoided whenever possible. To be more accurate, you should be careful to use object member only when necessary. For instance, there's no reason to read the value of an object member more than once in a single function:

    由于所有这些性能问题与对象成员有关,所以如果可能的话请避免使用它们。更确切地说,你应当小心地,只在必要情况下使用对象成员。例如,没有理由在一个函数中多次读取同一个对象成员的值:

 

function hasEitherClass(element, className1, className2){
  return element.className == className1 || element.className == className2;
}

    In this code, element.className is accessed twice. Clearly this value isn't going to change during the course of the function, yet there are still two object member lookups performed. You can eliminate one property lookup by storing the value in a local variable and using that instead:

    在此代码中,element.className被访问了两次。很明显,在这个函数过程中它的值是不会改变的,但仍然引起两次对象成员搜索过程。你可以将它的值存入一个局部变量,消除一次搜索过程。修改如下:

 

function hasEitherClass(element, className1, className2){
  var currentClassName = element.className;
  return currentClassName == className1 || currentClassName == className2;
}

    This rewritten version of the function limits the number of member lookups to one. Since both member lookups were reading the property's value, it makes sense to read the value once and store it in a local variable. That local variable then is much faster to access.

    此重写后的版本中成员搜索只进行了一次。既然两次对象搜索都在读属性值,所以有理由只读一次并将值存入局部变量中。局部变量的访问速度要快得多。

 

    Generally speaking, if you're going to read an object property more than one time in a function, it's best to store that property value in a local variable. The local variable can then be used in place of the property to avoid the performance overhead of another property lookup. This is especially important when dealing with nested object members that have a more dramatic effect on execution speed.

    一般来说,如果在同一个函数中你要多次读取同一个对象属性,最好将它存入一个局部变量。以局部变量替代属性,避免多余的属性查找带来性能开销。在处理嵌套对象成员时这点特别重要,它们会对运行速度产生难以置信的影响。

 

    JavaScript namespacing, such as the technique used in YUI, is a source of frequently accessed nested properties. For example:

    JavaScript的命名空间,如YUI所使用的技术,是经常访问嵌套属性的来源之一。例如:

 

function toggle(element){
  if (YAHOO.util.Dom.hasClass(element, "selected")){
    YAHOO.util.Dom.removeClass(element, "selected");
    return false;
  } else {
    YAHOO.util.Dom.addClass(element, "selected");
    return true;
  }
}

    This code repeats YAHOO.util.Dom three times to access three different methods. For each method there are three member lookups, for a total of nine, making this code quite inefficient. A better approach is to store YAHOO.util.Dom in a local variable and then access that local variable:

    此代码重复YAHOO.util.Dom三次以获得三种不同的方法。每个方法都产生三次成员搜索过程,总共九次,导致此代码相当低效。一个更好的方法是将YAHOO.util.Dom存储在局部变量中,然后访问局部变量:

 

function toggle(element){
  var Dom = YAHOO.util.Dom;
  if (Dom.hasClass(element, "selected")){
    Dom.removeClass(element, "selected");
    return false;
  } else {
    Dom.addClass(element, "selected");
    return true;
  }
}

    The total number of member lookups in this code has been reduced from nine to five. You should never look up an object member more than once within a single function, unless the value may have changed.

    总的成员搜索次数从九次减少到五次。在一个函数中,你绝不应该对一个对象成员进行超过一次搜索,除非该值可能改变。

 

Summary  总结

 

    Where you store and access data in JavaScript can have a measurable impact on the overall performance of your code. There are four places to access data from: literal values, variables, array items, and object members. These locations all have different performance considerations.

    在JavaScript中,数据存储位置可以对代码整体性能产生重要影响。有四种数据访问类型:直接量,变量,数组项,对象成员。它们有不同的性能考虑。

 

• Literal values and local variables can be accessed very quickly, whereas array items and object members take longer.

直接量和局部变量访问速度非常快,数组项和对象成员需要更长时间。


• Local variables are faster to access than out-of-scope variables because they exist in the first variable object of the scope chain. The further into the scope chain a variable is, the longer it takes to access. Global variables are always the slowest to access because they are always last in the scope chain.

局部变量比域外变量快,因为它位于作用域链的第一个对象中。变量在作用域链中的位置越深,访问所需的时间就越长。全局变量总是最慢的,因为它们总是位于作用域链的最后一环。


• Avoid the with statement because it augments the execution context scope chain. Also, be careful with the catch clause of a try-catch statement because it has the same effect.

避免使用with表达式,因为它改变了运行期上下文的作用域链。而且应当小心对待try-catch表达式的catch子句,因为它具有同样效果。


• Nested object members incur significant performance impact and should be minimized.

嵌套对象成员会造成重大性能影响,尽量少用。


• The deeper into the prototype chain that a property or method exists, the slower it is to access.

一个属性或方法在原形链中的位置越深,访问它的速度就越慢。


• Generally speaking, you can improve the performance of JavaScript code by storing frequently used object members, array items, and out-of-scope variables in local variables. You can then access the local variables faster than the originals.

 

一般来说,你可以通过这种方法提高JavaScript代码的性能:将经常使用的对象成员,数组项,和域外变量存入局部变量中。然后,访问局部变量的速度会快于那些原始变量。

 

    By using these strategies, you can greatly improve the perceived performance of a web application that requires a large amount of JavaScript code.

    通过使用这些策略,你可以极大地提高那些需要大量JavaScript代码的网页应用的实际性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值