0

私はこれをMDN の例として見ましたが、なぜこれが Good Thing (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>  
4

5 に答える 5

2

この場合size、囲まれているのは変数です。呼び出すmakeSizer(12)と、12 を「記憶する」関数参照が返されます。この関数参照は、要素のクリック ハンドラに割り当てられます (MDN の例の残りのコードを参照してください)。それは言います:あなたが私をクリックしたら、(実行)を呼び出してくださいsize12makeSizer(12)クリックすると、 から返された関数参照が実行されるため (囲まれた値は 12) 、本文のフォント サイズは '12px' になります。

この関数を使用した場合、フォントのサイズをすぐに変更したことになります。

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か?

リンク先の MDN ページは、 jsfiddle の例へのリンクです。やってみて!

良いことも悪いことも、コミュニティのより宗教的な部分に喜んで任せます。このクロージャーは便利で、おそらく便利だと思います。

于 2012-06-26T05:38:13.550 に答える
1

どちらも優れていませんが、動作が異なります。

次のように返された関数を呼び出すまで、最初のサイズは実際にはサイズ変更されません。

size12();

2 番目の例では、最初に関数を宣言してから、それを 3 回呼び出します。すぐにサイズを 12px、次に 14px、最後に 16px に設定します。

于 2012-06-26T05:39:47.670 に答える
0

最初の例でmakeSizerは、関数を返します。2 番目の例では、何も返さず、誤解を招く名前が付いています。2つは完全に異なります。

最初の例の推論は、それmakeSizerが関数ファクトリであるということです。それは「サイザー」機能を作ります。size12size14、およびsize16は、 によって作成された特定の「サイザー」関数makeSizerです。それらのいずれかが後で呼び出されると、フォント サイズが設定されます。

2 番目の例では、最初にフォント サイズを 12 に設定し、次に 14 に、次に 16 に設定し、各段階で興味のない戻り値を変数に保存します。

于 2012-06-26T08:49:11.287 に答える
0

実際、そこにあるのは閉鎖の例ではありません。

ウィキペディアによると、クロージャーの定義は「その関数の非ローカル変数の参照環境を備えた関数」です。

簡単に言えば、周囲のスコープの変数を「囲む」関数です。

良い例は次のようなものです。

public Func<int> ClosureExample()
{
    int a = 1,
        b = 2;

    Func<int> closeIt = () => a + b;
    return closeIt;
}

これで何が起こっているのかを実際に見てみましょう。2 つの整数を宣言し、ラムダ式/クロージャ/匿名メソッド (すべて、ファーストクラス関数ジェネリックに割り当てられた定義の有効な名前) を使用して、この計算を実行するために使用されるファーストクラス関数を返します。囲まれた変数、別の場所。

closeIt は整数 a と b を囲んでいると言えます。これらの変数はクロージャーに属していませんが、クロージャーによって使用されています。

于 2012-06-27T14:47:54.887 に答える
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();

2 番目のケースの関数は、 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');

それらが「良い」か「悪い」かは、そのように分類するための基準に依存します。

于 2012-06-26T05:49:20.963 に答える