繁体   English   中英

访问闭包变量与对象变量的速度

[英]speed of accessing closure variable vs object variable

考虑以下代码:

var xx=1;
var ff=function(){
  return xx+1;
}
ff();    

var gg=function(){
  return gg.xx+1;
}
gg.xx=1;
gg();

这两种方法之间是否应该有明显的性能差异? 在我看来, ff函数应该执行得更快,因为它仅引用一个变量,而gg函数引用两个变量。 我正在开发游戏,并想利用我可能的所有速度技巧。

这已经被问过很多次了 唯一的区别是,这两个示例通常都不会称为闭包,它们是变量和属性解析的简单情况。

如果是:

var xx = 1;
var ff = function(){
  return xx + 1;
}

然后在函数中,必须首先在局部变量对象上解析xx ,然后在作用域链上解析。 因此,至少要进行两次查询。

如果是:

var gg = function(){
  return gg.xx + 1;
}
gg.xx = 1;

在函数中,必须以与第一种情况完全相同的方式解析gg (即在局部变量对象上,然后在范围链上),这也是两次查找。 找到gg之后 ,必须搜索它的属性find xx ,这可能涉及许多查找。

鉴于以上所述,逻辑上假设第一个更快。

当然,这只是一个逻辑推断,性能实际上可能与此相反。 在某些浏览器中,无论作用域链的长度如何,全局变量查找都比局部查找快。 去搞清楚。

可以肯定的是,无论使用哪种浏览器,性能在不同的浏览器中都会有所不同。 这样的性能调整(如果有任何性能优势的话)正在发挥作用,应被视为过早的优化。

编辑

将其编码为闭包需要类似以下内容:

var gg = (function() {
  var g;
  return function() {
    gg = function() {
      return g.xx + 1; // Here is the closure
    }

    if (typeof g == 'undefined') {
      g = gg;
    }

    if (typeof g.xx == 'undefined') {
      g.xx = 1;
    }

    return g();
  }
}());

由于gg在IIFE完成之前没有值,因此只能在该点创建闭包,因此只有在函数首次运行时才可以分配该值。

注意, g必须仍然在局部变量对象上解析,然后在作用域链上解析,因此仍然要进行两次查找,并且没有从闭包中获得任何收益(至少没有逻辑上的收益)。

编辑2

为了清楚起见,请注意以下几点:

var xx = 1;
var ff = function(){
  return xx + 1;
}

技术上讲,它 不会 构成闭包,但是却不值得一认。 标识符xx在范围链上解析,当某些外部执行上下文完成时,范围链上没有ff可访问的变量。 因此闭包仅在函数存在的时间内存在,因此没有比词法范围更显着的了。

相反:

var ff = (function() {

  var closureVariable;

  // This "inner" function has a closure with closureVariable
  // If value is undefined, get (return) the value. Otherwise, set it
  return function(value) {
    if (typeof value == 'undefined') {
      return closureVariable;
    }
    closureVariable = value;
  };
}());

在这种情况下, ff拥有对closureVariable的独占访问 ,该变量是在创建它的函数完成后仍可访问的变量:

// set the value
ff('foo');

// get the value
console.log(ff());  // foo

ClosureVariable仅可通过ff访问(与全局变量不同),并且在多个调用上都可持久(与局部变量不同)。 闭包的这一功能使它们可以模仿私有成员

另一个功能是,许多函数可以对同一变量进行闭包(或特权访问),从而模仿一种继承。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM