2

私は Javascript のクロージャについてもっと調べようとしていますが、これを経験していました: https://developer.mozilla.org/en/JavaScript/Guide/Closures#Practical_closures

この記事によると、このような関数を使用することにより:

function makeSizer(size) {  
    return function() {  
        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;

size12、size14、size16 が内部関数へのアクセスを許可するクロージャーになるという概念は理解できますが、これは不要だと感じずにはいられません。持っている方が簡単ではありませんか:

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

、そしてこれらでそれを呼び出しますか?

document.getElementById('size-12').onclick = makeSizer(12);  
document.getElementById('size-14').onclick = makeSizer(14); 
document.getElementById('size-16').onclick = makeSizer(16);

私の考えが正しいかどうか誰かに教えてもらえますか-または、私はJavascriptの初心者で、このシナリオでクロージャーを使用する利点を理解していない可能性があります。その場合、利点を説明できれば幸いですそうする。

よろしくお願いします。

4

3 に答える 3

3

いいえ、できません。

それはあなたが書いたかのようです:

document.getElementById('size-12').onclick = (function(size) {  
    document.body.style.fontSize = size + 'px';  
})(12);

関数はすぐに呼び出され、スタイルはすぐに適用され.onclick、関数の戻り値が であるため、ハンドラーは登録されませんundefined

この例の本当のポイントは、別の関数から関数を返すことができ、その結果をイベント ハンドラーに割り当てることができることを示すことです。


変更しないままmakeSizer()にしておくと、中間変数なしで提案どおりにハンドラーを割り当てることができます。つまり、次のようになります。

document.getElementById('size-12').onclick = makeSizer(12);

ただし、説明した方法を変更すると機能しません。makeSizer()

また、同じサイザーを複数回使用する場合、「サイザー」を変数に格納するよりも効率が悪くなります。

于 2012-04-27T09:41:41.773 に答える
1

はい、これらの変数(sizeN)は不要です。結果をハンドラーとして直接割り当てることができmakeSizer()ます。これははるかに見栄えがします。

ただし、これらの変数の使用はクロージャの概念ではありません。この例のクロージャは関数であり、(引数がなくても)関数makeSizerを返しますが、それでも変数にアクセスできます。size

ただし、違いを確認する必要があります

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

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

実行makeSizer(5)は何もしません。呼び出されたときにサイズを事前定義されたサイズに設定する関数を返します。代わりに、実行するresize(5)とサイズが直接設定されます。後者の関数の結果をイベントハンドラーとして使用することはできません。

于 2012-04-27T09:45:06.907 に答える
1

あなたが提示した例では、もちろん閉鎖は必要ありませんが、概念を簡単に提示するためのものだと思います. ただし、クロージャが最適な解決策である場合もあります。javascriptで「プライベート」属性を実装する方法や、引数をカプセル化するためにカリー化が必要な場合 (つまり、コールバック関数用) について考えてみてください。

次の例が役立つことを願っています。

var makeSequencer = function() {
    var _count = 0; // not accessible outside this function
    var sequencer = function () {
        return _count++;
    }
    return sequencer;
}

var fnext = makeSequencer();
var v0 = fnext();     // v0 = 0;
var v1 = fnext();     // v1 = 1;
var vz = fnext._count // vz = undefined
于 2012-04-27T09:59:04.760 に答える