【问题标题】:Function scope if statements函数范围 if 语句
【发布时间】:2015-01-30 16:34:33
【问题描述】:

我正在尝试不寻常的 Javascript '模式',如果在父范围中声明变量是不可取的,我想了一种潜在的巧妙的方法来确定块的范围。

例如,而不是:

function someFunction () {
  var x, t;

  for (x = 0; x < 10000; x += 1) {
    if (true) {
      t = x;
    }
  }
}

可以使用以下方法保存额外的父变量:

function someFunction () {
    var x;

    for (x = 0; x < 10000; x += 1) {
      if (true) { void function () {
        var t = x;
      }(); }
    }
}

但是,我的 jsperf (http://jsperf.com/scoped-if) 表明,如果重复使用,可能会对性能产生负面影响。显然,这个结果表明上述不是一种实用的模式,除非执行得非常谨慎。

我了解缓慢可能是重复创建和销毁执行上下文 (1 + 10000),而第一次只涉及 1。

我的问题是,考虑到上述条件(不在循环中使用),这种模式是否仍然有用,为什么创建上下文的成本如此之高?

【问题讨论】:

  • 我不会尝试优化它,而是优化循环内部的内容,通常这需要接近 100% 的计算时间
  • 当然,这种“模式”的目的只是为了避免使用仅在块内使用的变量污染父范围。

标签: javascript scope execution-time anti-patterns


【解决方案1】:

是的,IIFE 是模拟block scope 的合理方式。

更好的方法是使用let,如果需要,可以使用 ES6 转译器:

function someFunction () {
    var x;

    for (x = 0; x < 10000; x += 1) { 
      if (true) { 
        let t = x;
        // Do something with t here
      }
      // because it is not defined here
    }
    // or here
}
// and even a var wouldn't be defined here

ES6 compatibility table for let

【讨论】:

  • 使用 IIFE 模拟块作用域的原因是提供一个向后兼容的替代 let 关键字。感谢您提供这个作为一个潜在的解决方案,当 ES6 被广泛实施时,这绝对是使用的方法。
  • 我认为答案是let + Traceur/6to5 或 node --harmony/io.js 可以,而 IIFE 则不能。但不在未知长度的循环内:)
猜你喜欢
  • 2012-06-09
  • 2017-04-28
  • 1970-01-01
  • 2016-08-17
  • 1970-01-01
  • 2021-10-30
  • 2014-01-07
  • 2019-03-18
  • 1970-01-01
相关资源
最近更新 更多