我认为这是一个example on 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>
答案 0 :(得分:2)
在这种情况下,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
后会发生什么?
您链接到jsfiddle example的链接的MDN页面。试试吧!
好或坏是我乐于留给社区中更加宗教的部分的事情。我想说这个闭包很有用,也许很方便。
答案 1 :(得分:1)
它们都不是更好,但它们的行为不同。
在您按如下方式调用返回的函数之前,第一个实际上不会调整大小:
size12();
你的第二个例子首先声明一个函数,然后调用它3次。您立即将大小设置为12px然后是14px,最后是16px。
答案 2 :(得分:0)
“好”的标准是什么?
在第一个示例中,您创建了一些必须调用才能完成工作的函数。尺寸保持在封闭状态,很难看到任何好处。您可能想要这样做:
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');
他们是“好”,“坏”还是其他什么取决于你对它们进行分类的标准。
答案 3 :(得分:0)
在第一个示例中,makeSizer
返回一个函数。在第二个示例中,它不返回任何内容,并且具有误导性的名称。两者完全不同。
第一个例子中的推理是makeSizer
是函数工厂;它使“sizer”功能。 size12
,size14
和size16
是由makeSizer
制作的特定“sizer”函数。如果稍后调用其中一个,它将设置字体大小。
在第二个示例中,首先将字体大小设置为12,然后设置为14,然后设置为16,并在每个阶段将不感兴趣的返回值保存到变量中。
答案 4 :(得分:0)
实际上,你所拥有的是而不是一个闭包的例子。
维基百科告诉我们,closure的定义是“函数以及该函数的非局部变量的引用环境。”
更简单地说,它是一个“包围”周围范围变量的函数。
一个很好的例子是这样的:
public Func<int> ClosureExample()
{
int a = 1,
b = 2;
Func<int> closeIt = () => a + b;
return closeIt;
}
让我们真正看看这是怎么回事。我们声明两个整数,然后使用lambda表达式/ closure / anonymous方法(所有都是分配给第一类函数generic的定义的有效名称)来返回将用于执行此计算的第一类函数,使用随附的变量,在其他地方。
你可以说closeIt包含整数a和b;这些变量不属于闭包,但它们正在被它使用。