【问题标题】:Lexical environment example explanation词法环境示例说明
【发布时间】:2017-11-17 14:15:39
【问题描述】:

我正在关注一个 JS 教程,并在下面遇到了这个示例,从我目前所学到的知识来看,第一个是有道理的:

function makeCounter() {
  function counter() {
    return counter.count++;
  };
  counter.count = 0;

  return counter;
}

let counter = makeCounter();
let counter1 = makeCounter();
console.log(counter());  // 0
console.log(counter());  // 1
console.log(counter1()); // 0

所以,这是有道理的,因为每次我们将 makeCounter 函数分配给新变量时都会创建新的词法环境。我不明白的是,如果我使用函数makeCounter 的属性,如果我将makeCounter.count 分配给新变量,我仍然会增加它:

function makeCounter() {
  function counter() {
    return makeCounter.count++;
  };
  makeCounter.count = 0;

  return counter;
}

let counter = makeCounter();
let counter1 = makeCounter();
console.log(counter());  // 0
console.log(counter());  // 1
console.log(counter1()); // 2

【问题讨论】:

  • 这是怎么复制的?
  • @AjayGaur 这不是那个问题的重复。
  • 在javascript中,语法makeCounter.count = 0;(带有函数名,不在实例上)相当于静态属性,而this.count = 0;是非静态的

标签: javascript


【解决方案1】:

我认为在这里使用函数对象的属性会很混乱,尤其是如果您想了解词法环境。一个更好的例子可能是

function makeCounter() {
  var count = 0;
  function counter() {
    return count++;
  }
  return counter;
}

var count = 0;
function makeCounter() {
  function counter() {
    return count++;
  }
  return counter;
}

更明显的是有多少count 变量,它们是在什么时候创建的,以及它们存在于哪个范围内。当然,它与通过countermakeCounter 变量(使用函数对象初始化)的间接作用相同,它们与count 在我的示例中的作用域相同。

诚然,makeCounter.count = 0 最好位于 makeCounter 之外,否则重置全局计数的行为会真的令人困惑。与您对应的确切无属性代码将是

function makeCounter() {
  var count;
  function counter() {
    return count++;
  }
  count = 0;
  return counter;
}

var count;
function makeCounter() {
  function counter() {
    return count++;
  }
  count = 0;
  return counter;
}

【讨论】:

    【解决方案2】:

    函数 counter 和 counter.count 在每次调用时都在 makeCounter 的函数范围内新定义。 makeCounter.count 仅针对全局范围定义一次。

    【讨论】:

      【解决方案3】:

      我不明白的是如果我使用函数的属性 makeCounter 如果我分配,我仍在增加 makeCounter.count 将它添加到新变量:

      makeCounter在它定义的范围内可用makeCounter定义内

      因此,由于makeCounter.count 的作用域并非仅限于makeCounter 函数定义的本地范围,因此countercounter1 都可以访问makeCounter.count 的相同引用。

      【讨论】:

        【解决方案4】:

        每次都会创建新的词法范围,当 makeCounter() 返回时,它会记住 clojure 中的计数值。简单来说,它是一种语言特性,允许函数从定义函数的范围内记住变量。

        它允许在 Javascript 中创建类似于变量的“私有”。

        【讨论】:

          猜你喜欢
          • 2018-09-05
          • 2019-10-27
          • 2012-02-16
          • 2015-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-02
          相关资源
          最近更新 更多