1

クロージャーに関する mozdev の記事を読んでいますが、次のフィドルの例があります。

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

アイデアは、クリックイベントからサイズを指定してmakeSizerを呼び出し、フォントサイズを変更することです。しかし、名前のない関数を切り取ってこれを行うと:

function makeSizer(size) {
    document.body.style.fontSize = size + 'px';
}

size16 のリンクがクリックされ、リンクにオンクリック イベントがなくなったかのように、クリック可能なリンクは効果を失い、フォント サイズは直接最大になります。追加returnしても動作は変わりません。

(私が何について話しているのかわからない場合は、例の上にあるリンクをクリックしてください。フィドルがあります)

私の質問は、なぜこれにクロージャー/コールバックが必要なのですか? 簡単なステートメントが機能するべきではありませんか?関数の呼び出しに関するものである場合、スクリプトがロードされた後に機能しないのはなぜですか? 関数呼び出しが呼び出しを待つのではなく、サイズを直接変更するようになった (そして size16 が最後に呼び出された) ため、デフォルトで最後のサイズになる理由がわかりましたが、ページが読み込まれた後に機能しないのはなぜですか?

4

6 に答える 6

2

コールバックなしで何が起こっているかというと、スクリプトがロードされるときに、サイズが 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;
于 2013-10-02T09:50:58.273 に答える
1

割り当てる値はonclick、クリック イベントを引数としてブラウザによって呼び出される関数である必要があります。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'ます。

于 2013-10-02T09:58:18.123 に答える
1

質問に答えるには: font-size の変更にはクロージャは必要ありません。

内部関数の削除が機能しない理由について説明します。

makeSizerイベントハンドラではありません。関数を作成して返す関数です。これらの関数はイベント ハンドラーです。少し分解してみましょう。

var size12 = makeSizer(12);
document.getElementById("size-12").onclick = size12;

最初の行は、パラメーターとして12makeSizerを使用して関数を実行します。body の font-size を 12 に設定してそれを返す別の名前のない関数を作成します。つまり、変数は によって作成された関数を保持するようになりました。関数自体を保持しません。size12makeSizersize12makeSizer

size122 行目で、クリック可能な要素の onclick-Event に割り当てます。したがって、このイベントのイベント ハンドラは、font-size を 12 に設定する関数になりました。関数は実行されませmakeSizer

内部関数がなくなるように関数を変更すると、makeSizer何も返されないため、変数size12は「空」になります。次に、size12onclick-Event を割り当てるときに、onclick-Event に「何も」を割り当てます。そのため、何も起こりません。

于 2013-10-02T10:00:13.760 に答える
0

クリック イベントでフォント サイズを切り替えているため、クリック イベントが実行されたときにイベント ハンドラーとして機能する関数を割り当てる必要があります。

コード例では、関数は変数に格納され、関数の戻り値が割り当てられ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);
};
于 2013-10-02T09:59:20.320 に答える
0

onclickイベントには機能が必要なためです。したがって、 return だけdocument.body.style.fontSize = size + 'px';では実行されません。

于 2013-10-02T09:55:03.240 に答える
0

動作しない例では、変数を定義するとすぐに

var size12 = makeSizer(12);

makeSizer(12)関数を実行してサイズを変更する呼び出しを行っています。

対照的に、実際の例では、変数を定義すると

var size12 = makeSizer(12);

パラメータを使用して関数(makeSixer()この場合はそれが返されます)を作成しています12が、関数を返すだけなので、それを実行していません。

于 2013-10-02T09:55:25.997 に答える