I've been reading the mozdev article on closures and it has this fiddle example:
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
the idea is to call makeSizer with a size, from an on-click event and it changes the font size. But if you cut out the nameless function and just do this:
function makeSizer(size) {
document.body.style.fontSize = size + 'px';
}
the clickable links stop having any effect and font size goes directly to the largest, as if the size16 link was clicked and the links don't have an on-click event anymore. Adding return
doesn't change the behaviour.
(if it's unclear what I'm talking about, click the links above the examples, they have the fiddles)
My question is, why does this need closures/callbacks? Shouldn't a simple statement work? If it's about making a call to a function, why doesn't it work after the script loads? I get why it would default to the last size, since the function call now directly alters the size (and size16 is called last), instead of waiting for the call, but still, why doesn't it work after the page loads?
要回答你的问题:改变字体大小并不需要关闭。
我们为什么去除内功能不起作用:
makeSizer
不是事件处理程序。 那是制造功能和返回它们的功能。 这些功能是事件处理程序。 让我们把它分解一下:
var size12 = makeSizer(12);
document.getElementById("size-12").onclick = size12;
第一行执行函数makeSizer
12作为参数。 它创建另一种无名函数,套在身上的字体大小,以12和返回。 这意味着,该变量size12
现在认为已经被创建的函数makeSizer
。 size12
不按住功能makeSizer
本身。
在第二行分配size12
可点击元素的onclick的事件。 因此,此事件的事件处理程序,现在是设定字体大小为12它不执行的函数的函数makeSizer
!
如果你改变了功能makeSizer
,以便有没有内在的功能了,它不返回任何东西,因此变量size12
是“空”。 然后,当你指派size12
的的onclick-事件,分配“一无所有”到的onclick的事件。 这就是为什么没有任何反应。
发生了什么事,而不回调的大小是在快速连续设置为12,然后14,然后16脚本加载。
需要回调,因为你要定义链接被点击的时候会发生什么。
要了解与版本makeSizer
,你应该先了解以下的版本,它应该做同样的事情:
var setSize12 = function() { document.body.style.fontSize = '12px'; };
var setSize14 = function() { document.body.style.fontSize = '14px'; };
var setSize16 = function() { document.body.style.fontSize = '16px'; };
document.getElementById('size-12').onclick = setSize12;
document.getElementById('size-14').onclick = setSize14;
document.getElementById('size-16').onclick = setSize16;
分配给该值onclick
需要是一个会通过点击事件作为一个参数的浏览器中得到调用的函数。 您希望您的功能与尺寸参数来调用。 这是行不通的。
解决的办法是找到大小绑定在传递到的onclick功能,并为您使用闭包的方式。
如果您在mozdev代码仔细观察,你会看到,当onclick处理他们分配不能指望任何参数的函数:
function(){ document.body.style.fontSize = size + 'px'; }
这个功能确实使用size
可变的,但它不是在它的范围界定。 相反,他们创造超过在该尺寸变量定义功能的关闭。 这个封闭他们通过你想给参数:
function makeSizer(size) {
// size is defined here, because it is a parameter
return function() {
// same size is here
document.body.style.fontSize = size + 'px';
};
}
的返回值makeSizer('12px')
是上面说的函数改变fontSize的不带参数并结合于尺寸可变'12px'
。
在非工作示例,只要你定义变量
var size12 = makeSizer(12);
您呼叫makeSizer(12)
执行该功能并更改大小。
与此相反,在工作例如,当你定义变量
var size12 = makeSizer(12);
要创建一个功能(这是makeSixer()
在这种情况下返回)与参数12
,但因为你只是回到你不执行它的功能。
由于onclick
事件需要的功能。 所以,当你刚刚返回document.body.style.fontSize = size + 'px';
,它没有得到执行。
由于您的切换上的click事件的字体大小,你需要分配功能时进行点击事件作为事件处理程序。
在代码示例中,所述功能被存储到变量,被分配了的返回值makeSizer
功能。
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
这需要makeSizer
保留提供的参数的值,以便它可以在事件实际上是发射引用。 封闭是用于调用内部功能时,保留的外功能的范围的机构。 在内部函数存储在变量这种情况下,你已经宣布和被称为onclick
每个相应锚标记。 那些倒闭包含size
当函数被宣布感谢关闭提供的参数。
老实说,我认为这仅仅是一个坏榜样。 如果我设置通过Javascript的字体大小,我会简单地使用匿名函数:
document.getElementById("something").onclick = function(){
document.body.style.fontSize = '16px';
};
或与功能:
document.getElementById("something").onclick = function(){
makeSizer(12);
};
文章来源: Why does changing font size with an event through javascript require closures?