为什么通过javascript通过事件更改字体大小需要闭包?

为什么通过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号链接,链接不再有点击事件一样。添

我一直在阅读mozdev关于闭包的文章,其中有一个fiddle示例:

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