这是闭包的一个很好的例子吗?
is this a good example of a closure?
我在MDN上看到了一个例子,不明白为什么这是一件好事(TM)。
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
为什么上面比下面更好?
function makeSizer(size) {
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>
在这种情况下size
是封闭的变量。调用 makeSizer(12)
将返回一个"记住"12 的函数引用。此函数引用分配给元素上的单击处理程序(请参阅 MDN 示例中的其余代码)。它说:如果你点击我,调用(执行)size12
。因此,单击时,正文的字体大小变为"12px",因为执行从makeSizer(12)
返回的函数引用(包含的值为 12)。
如果您使用该功能,您将立即调整字体大小。
function makeSizer(size) {
document.body.style.fontSize = size + 'px';
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16); //=> now the font-size of the body is '16px'
想想当你这样做时,在这种情况下会发生什么:
document.getElementById('size-12').onclick = size12;
如果你点击#size-12
会发生什么吗?
您链接到的 MDN 页面链接到一个 jsfiddle 示例。试试吧!
好坏是我很乐意留给社区中更虔诚的部分的事情。我会说这个关闭是有用的,甚至可能很方便。
它们都不是更好的,但它们的行为不同。
在调用返回的函数之前,第一个不会实际大小,如下所示:
size12();
第二个示例首先声明一个函数,然后调用它 3 次。您立即将大小设置为 12px,然后是 14px,最后是 16px。
你对"好"的标准是什么?
在第一个示例中,您将创建一些函数,然后必须调用这些函数才能完成工作。大小被固定在封闭中,很难看到任何好处。您可能希望执行以下操作:
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var setSmall = makeSizer(8);
var setMedium = makeSizer(10);
var setLarge = makeSizer(14);
或类似,所以现在您只需调用:
setSmall();
第二种情况下的函数应该称为 setSize 之类的函数。
闭包的另一个用途是:
var setSize = (function() {
var sizes = {small: 8, medium: 10, large: 14};
return function(size) {
if (sizes.hasOwnProperty(size)) {
document.body.style.fontSize = sizes[size] + 'px';
}
}
}());
setSize('small');
它们是"好"、"坏"还是其他什么,取决于您对它们进行分类的标准。
在第一个示例中,makeSizer
返回一个函数。在第二个示例中,它不返回任何内容,并且具有误导性名称。两者完全不同。
第一个例子中的推理是makeSizer
是一个函数工厂;它产生"sizer"函数。 size12
、size14
和size16
是特殊的"大小"函数,由makeSizer
产生。如果稍后调用其中一个,它将设置字体大小。
在第二个示例中,首先将字体大小设置为 12,然后设置为 14,然后设置为 16,并在每个阶段将不感兴趣的返回值保存到变量中。
实际上,您那里没有闭包的例子。
维基百科告诉我们,闭包的定义是"函数以及该函数的非局部变量的引用环境"。
更简单地说,它是一个"包围"周围范围的变量的函数。
一个很好的例子是这样的:
public Func<int> ClosureExample()
{
int a = 1,
b = 2;
Func<int> closeIt = () => a + b;
return closeIt;
}
让我们真正看看这其中发生了什么。 我们声明两个整数,然后使用 lambda 表达式/闭包/匿名方法(都是分配给第一类函数泛型的定义的有效名称)返回将用于执行此计算的第一类函数,使用封闭的变量,在其他地方。
你可以说closeIt包含整数a和b;这些变量不属于闭包,但它们被它使用。
- 我在下拉列表中尝试了下一个和前五年的html代码.接下来的5年我都过得很好.我怎样才能拿到之前的5年
- html5:一个很好的加载方法
- Javascript是一个很好的日期选择器和时间选择器库
- 这是一个很好的例子,显示了 JavaScript 中的 OOP 和过程编程之间的区别
- 一个很好的JS库,用于容纳电气原理图
- 立即调用角控制器内部的函数,这是一个很好的实践
- 一个很好的方法来抵消所有绘制到画布上的0.5像素
- 如何获得一个就绪函数和另一个函数在 document.ready 中很好地播放
- 一个很好的文本到语音转换JavaScript库
- 这是闭包的一个很好的例子吗?
- 将异步 API 转换为同步 API.(我保证有一个很好的理由)
- 同时分配和检查并有一个很好的语法错误
- JavaScript不能在一个网站上工作,但在另一个网站上很好
- 有一个功能可以将字符串很好地缩短为一个、两个或三个字母
- 在 Object.prototype 上为 NodeList 对象实现数组方法是否是一个很好的实践?
- 什么'这是一个很好的webrtc音频解决方案
- 在实时评论系统中,有一个不变的排序是一个很好的实践
- 这是一个很好的方法,可以查看是否从内容可编辑的DOM中删除了某些内容
- 它是一个很好的私人数据传输和保护解决方案吗
- Meteor findOne查询在一个模板助手中返回未定义的结果.在其他模板助手中,同样的查询也能很好地工作