词汇环境示例说明

时间:2017-11-17 14:15:40

标签: javascript

我正在关注一个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

4 个答案:

答案 0 :(得分:1)

函数计数器和counter.count在每次调用的makeCounter函数范围内定义为new。 makeCounter.count只为全局范围定义一次。

答案 1 :(得分:1)

我认为在这里使用函数对象的属性非常混乱,特别是如果你想了解词汇环境。一个更好的例子可能是

之间的区别
function makeCounter() {
  var count = 0;
  function counter() {
    return count++;
  }
  return counter;
}

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

更明显的是,有多少count个变量,它们何时被创建,以及它们所处的范围。当然,它通过counter vs makeCounter变量(用函数对象初始化)的间接作用相同,它们与我的例子中的count生活在相同的范围内。 / p>

不可否认,makeCounter.count = 0最好超出makeCounter,否则重置全局计数的行为会让真正混淆。与您的对应的确切无属性代码将是

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

VS

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

答案 2 :(得分:0)

  

我不明白的是,如果我使用该功能的属性   SLComposeViewController *composeVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];如果我分配,我仍在递增makeCounter   它到新的变量:

makeCounter.count 在定义范围makeCounter定义的范围内可用。

因此,由于makeCounter的范围不是makeCounter.count函数定义的本地范围,因此makeCountercounter都可以访问counter1的相同引用

答案 3 :(得分:0)

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

它允许在Javascript中使'private'变量。