【问题标题】:The appropriateness of an example regarding closure on the MDN docs关于 MDN 文档关闭的示例的适当性
【发布时间】:2014-05-16 15:36:46
【问题描述】:

MDN topic for closures, 上,他们将此示例展示为“真实世界”应用程序。

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

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

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

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


document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>

我的问题是:完全消除闭包并像 document.getElementById('size-12').onclick = 12; 中那样直接分配大小不是更简单吗? (因此这是一个不好的例子?)这里的做法看起来很像 rube-goldberg。

进一步扩展,我觉得一个更突出的例子是保持闭包,但让文档元素直接从元素的 id 检索文本大小,所以我们只需要一个语句而不是三个 (每个文本大小一个)。我不确定它是如何实现的,但可能类似于

document.getElementById(这里有一些函数来监听点击并注册被点击元素的 id).onclick = makeSizer(一些正则表达式来解析文本大小的 id )

这有可能吗?如果是这样,这是否被认为是最佳做法?

【问题讨论】:

  • 这是一个最小的例子。当然,他们可以为您提供一个真实世界的示例,其中处理程序非常大,因此可以从这种方法中获得更多好处,以避免重复代码,但是这个示例说明了重点。是的,他们可以从 ID 中解析出数字。但这并不总是可能的。
  • ...我在该页面上看不到示例被称为“真实世界”的任何地方。它们是简单实用的例子。重要的是要了解这种方法,以便在遇到特定情况时知道如何去做。

标签: javascript closures


【解决方案1】:

我的问题是:完全消除闭包并像document.getElementById('size-12').onclick = 12; 中那样直接分配大小不是更简单吗?

不完全是。您必须重复一遍:

document.getElementById('size-12').onclick = function () {
    document.body.style.fontSize = '12px';
};
document.getElementById('size-14').onclick = function () {
    document.body.style.fontSize = '14px';
};
document.getElementById('size-16').onclick = function () {
    document.body.style.fontSize = '16px';
};

首先让我们创建一个独立于参数的函数...

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

但仅凭这一点你并没有太大进步:

document.getElementById('size-12').onclick = function () {
    resize(12);
};
document.getElementById('size-14').onclick = function () {
    resize(14);
};
document.getElementById('size-16').onclick = function () {
    resize(16);
};

闭包允许您保留单个实现,同时还保留单个函数调用的上下文(在本例中为“事件处理程序的调用”):

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

document.getElementById('size-12').onclick = makeSizer(12);
document.getElementById('size-14').onclick = makeSizer(14);
document.getElementById('size-16').onclick = makeSizer(16);

这个例子的重点是,当你使用闭包时,你可以分配一个完整的函数带参数


[...] 让文档元素直接从元素的 id 检索文本大小,[...]

当然,这是可能的,但是你不再需要闭包了,因为函数可以自己找出上下文:

var resize = function () {
    var size = this.id.split('-').pop();
    document.body.style.fontSize = size + 'px';
};

document.getElementById('size-12').onclick = resize;
document.getElementById('size-14').onclick = resize;
document.getElementById('size-16').onclick = resize;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多