2016-06-12 10 views
0

次のJavaScriptを書くのがますます増えています。これが共通のパターンかどうかを知りたいと思います。コードパターンのこれは有効なパターンで、それは何と呼ばれていますか?

パート:

var fruits = ["pear", "apple", "banana"]; 

var getNextFruit = function() { 
    var _index = 0, 
     _numberOfFruits = fruits.length; 

    getNextFruit = function() { 
     render(fruits[_index]); 
     _index = (_index + 1) % _numberOfFruits; 
    } 
    getNextFruit(); 
}; 

は私が機能を再定義し、それをすぐに呼び出す関数内で、パラメータを取らない機能を持っています。関数型言語では、これは返される関数である可能性があります.JavaScriptを使用すると、関数の名前を再利用できるため、JavaScriptが簡単になります。したがって、実装を変更することなく機能を拡張することができます。

このパターンは、あなたの「キャッシュ」がラップアラウンド状態であるメモ作成に非常に便利だと想像することもできます。

私は時には意味がある場合に状態を得ることができる関数のgetまたはsetメソッドでこれを実装します。追加されたフィドルはこれの例を示しています。

これは主にJavaScriptを志向質問ですので:The obligatory fiddle

+0

基本的なデータ型を気にせずに、コレクションの要素を1つ1つ「生成」することは、[iterator](https://en.wikipedia.org/wiki)と呼ばれています。/Iterator_pattern)パターンである。 –

+1

このパターンは「自己定義関数」と呼ばれ、Stoyanovの本「Javascript Patterns」に導入されました –

+0

関数内に 'fruits'変数と配列を定義しないのはなぜですか? – nnnnnn

答えて

2

私は機能を再定義し、それをすぐに呼び出す関数内で、パラメータを取らない機能を持っている:私のバージョンでは、再利用可能なサービスを行うことができます。 これは有効なパターンで、それは何と呼ばれていますか?

関数を再定義することは、通常反パターンです。これは多くのことを複雑にするためです。はい、関数内にif (alreadyInitialised)条件を入れるよりも、関数全体を交換するほうが効率的な場合もありますが、その価値はほとんどありません。パフォーマンスを最適化する必要がある場合は、両方のアプローチを試してみることもできますが、そうでなければできるだけシンプルに保つことがアドバイスです。

"最初の呼び出しで初期化"というパターンは、純粋な計算(関数プログラミング)ではlaziness、オブジェクト(OOPでは)の場合はsingletonとして知られています。

しかし、ほとんどの場合、オブジェクト/関数/モジュールの初期化を初めて使用するまで延期する理由はほとんどありません。それのために取られたリソース(時間とメモリの両方)は重要ではありません。特に、少なくとも1回あなたのプログラムでそれを必要としていることが確かなときには重要です。そのためには、JavaScriptでIIFEを使用します。これは、オブジェクトの作成時にはmodule patternとも呼ばれます。

+0

この怠惰のコンセプトと、JavaScriptにどうやって適用するかということについて、私の頭の中には本当に時間が必要です。私はこれが怠け者の実装であることが正しいかもしれないと思います。 –

1

閉鎖を経て機能を作成するには、JavaScriptではかなり一般的なパターンです。私は個人的に違ったことをするでしょう:

var fruits = ["pear", "apple", "banana"]; 

var getNextFruit = function(fruits) { 
    var index = 0, 
     numberOfFruits = fruits.length; 

    function getNextFruit() { 
     render(fruits[_index]); 
     index = (_index + 1) % numberOfFruits; 
    } 

    return getNextFruit; 
}(fruits); 

彼らはとにかく閉鎖にプライベートだから先頭のアンダースコアを持つ変数名を乱雑にする(私の意見では)何の正当な理由はありません。上記は、クロージャーの動作を外部変数名と結合しません。

function fruitGetter(fruits) { 
    var index = 0, numberOfFruits = fruits.length; 

    function getNextFruit() { 
     render(fruits[_index]); 
     index = (_index + 1) % numberOfFruits; 
    } 

    return getNextFruit; 
} 

// ... 

var getNextFruit = fruitGetter(someFruits); 

var otherFruits = fruitGetter(["kumquat", "lychee", "mango"]); 
+0

私は普段使用している奇妙な「コーディング標準」を除いて、あなたは下線について正しいです。 。リファクタリングを容易にし、変数を見逃さないようにします。質問に戻るには、クロージャがパターンですか?または、クロージャーは単なる言語機能ですか? –

+1

「クロージャ」は言語機能です。これは、(あなたのコードのように)関数を返す関数が呼び出されたときに「取得」されるローカル変数を保持するために作成され、維持される「オブジェクト」の用語です。 – Pointy

+0

アンダースコアを使用したい場合は、それを行い、それについてよく感じてください。彼らはちょうど私を悩ます:) – Pointy

関連する問題