为什么通过javascript通过事件更改字体大小需要闭包?
我一直在阅读mozdev关于闭包的文章,其中有一个fiddle示例:为什么通过javascript通过事件更改字体大小需要闭包?,javascript,html,css,dom,closures,Javascript,Html,Css,Dom,Closures,我一直在阅读mozdev关于闭包的文章,其中有一个fiddle示例: function makeSizer(size) { return function() { document.body.style.fontSize = size + 'px'; }; } 我们的想法是通过单击事件调用大小为的makeSizer,它会更改字体大小。但是,如果您删除了无名函数,只需执行以下操作: 可点击链接不再有任何效果,字体大小直接变为最大,就好像点击了16号链接,链接不再有点击事件一样。添
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
我们的想法是通过单击事件调用大小为的makeSizer,它会更改字体大小。但是,如果您删除了无名函数,只需执行以下操作:
可点击链接不再有任何效果,字体大小直接变为最大,就好像点击了16号链接,链接不再有点击事件一样。添加return
不会改变行为
(如果不清楚我在说什么,请单击示例上方的链接,它们有小提琴)
我的问题是,为什么需要闭包/回调?一个简单的陈述难道不管用吗?如果是关于调用函数,为什么在脚本加载后它不工作?我明白为什么它会默认为最后一个大小,因为函数调用现在直接改变大小(size16被调用为最后一个),而不是等待调用,但是,为什么页面加载后它不工作?没有回调的情况是,随着脚本加载,大小会快速连续设置为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;
在没有回调的情况下,当脚本加载时,大小会快速连续设置为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
事件需要一个函数。因此,当您返回document.body.style.fontSize=size+'px'代码>,它不会被执行。因为onclick
事件需要一个函数。因此,当您返回document.body.style.fontSize=size+'px'代码>,它不会被执行。在非工作示例中,定义变量后
var size12 = makeSizer(12);
var size12 = makeSizer(12);
您正在调用makeSizer(12)
,它执行函数并更改大小
相反,在工作示例中,定义变量时
var size12 = makeSizer(12);
var size12 = makeSizer(12);
您正在使用参数12
创建一个函数(在本例中是makeSixer()
返回的),但由于您只是返回函数,因此您没有执行它。在非工作示例中,定义变量后
var size12 = makeSizer(12);
var size12 = makeSizer(12);
您正在调用makeSizer(12)
,它执行函数并更改大小
相反,在工作示例中,定义变量时
var size12 = makeSizer(12);
var size12 = makeSizer(12);
您正在使用参数12
创建一个函数(在本例中是makeSixer()
返回的),但由于您只是返回函数,因此您没有执行它。您分配给onclick
的值需要是一个函数,浏览器将以click事件作为参数调用该函数。
您希望使用size参数调用函数。那不行
解决方案是找到一种方法,将大小绑定到传递给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'
您指定给onclick
的值必须是一个函数,浏览器将以click事件作为参数调用该函数。
您希望使用size参数调用函数。那不行
解决方案是找到一种方法,将大小绑定到传递给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'
,因为在单击事件上切换字体大小,所以在执行单击事件时,您需要分配一个函数作为事件处理程序
在代码示例中,函数被存储到变量中,并被赋予makeSizer
函数的返回值
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
这需要makeSizer
保留所提供参数的值,以便在实际触发事件时可以引用它。闭包是一种机制,用于在调用内部函数时保留外部函数的作用域。在这种情况下,内部函数存储在您声明的变量中,这些变量被称为每个锚标记的onclick
。这些闭包包含在函数由于闭包而声明时提供的size
参数
老实说,我认为这只是一个糟糕的例子。如果我通过Javascript设置字体大小,我只需使用匿名func