【问题标题】:JavaScript Closures: MDN Practical ClosuresJavaScript 闭包:MDN 实用闭包
【发布时间】:2014-10-21 02:54:29
【问题描述】:

关于explaining JavaScript closures to six-year olds 有一个很棒的stackoverflow 问题。

该问题提供了许多非常有用的答案。其中一个答案是Closures at the Mozilla Developer Network JavaScript guide 的条目,它确实提供了一个简洁易懂的解释(具体来说,闭包存储了一个函数 及其环境)。

但是,在 Practical Closures 下的 MDN 条目让我感到困惑……具体来说,在他们的示例中,哪里需要闭包来调整文本大小?有人可以为我澄清为什么他们需要关闭 makeSizer 函数吗?

作为一个初学者程序员,我只能假设我的不使用闭包的替代方案(如下所示)在某种程度上是幼稚和不正确的(尽管看起来更简洁和高效)?

当 MDN 条目显示时,我对关闭文本大小的理由特别感兴趣:

在其他函数中不必要地创建函数是不明智的 如果特定任务不需要闭包,因为它会 在处理速度方面对脚本性能产生负面影响 和内存消耗。

没有关闭的版本:

HTML(根据 MDN 原文修改)

<p>Some paragraph text</p>
<h1>some heading 1 text</h1>
<h2>some heading 2 text</h2>

<a href="#" class="sizer">12</a>
<a href="#" class="sizer">14</a>
<a href="#" class="sizer">16</a>

CSS(未修改)

body {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
}

h1 {
  font-size: 1.5em;
}
h2 {
  font-size: 1.2em;
}

JavaScript(修改)

(function makeSizer() {
   var sizers = document.getElementsByClassName('sizer');
    for (var i = 0; i < sizers.length; i++) {
        sizers[i].onclick = function () {document.body.style.fontSize = this.innerHTML + "px";};
    }; // close for...
})(); // close makeSizer;

JSFiddle (alternative to the original from MDN)

Original from MDN

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    它主要用于防止对象污染全局空间。在闭包中,您可以使变量成为局部变量和内部“实现”细节。闭包的主要好处实际上是能够创建私有范围。

    这里提出的性能论点确实与此级别的微优化有关,而不是实际问题。

    【讨论】:

    • 感谢您的回复。那么我提出的替代版本,document.getElementsByClassNamethis 用于.onclick 函数污染全局空间?我仍然不完全清楚带闭包的版本如何更好......
    【解决方案2】:

    如果您需要在某个名称空间中存储值并在以后重用它们,您可以使用闭包,而不是使用全局名称空间示例。

    全局命名空间:

    var i = 0;
    function inc() {
       i++;
       console.log(i);
    }
    inc(); // output 1 
    console.log(i); //output 1
    

    关闭:

    function closure() {
       var i = 0;
       return function() {
          i++;
          console.log(i);
       }
    }
    myClosure = new closure();
    myClosure(); //output 1;
    myClosure(); //output 2;
    console.log(i); //undefined
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 2022-07-06
      • 2018-09-09
      • 1970-01-01
      相关资源
      最近更新 更多