私はJavaScriptでこのパターンを見てきました:
var test = function () {
function test(args) {
this.properties = args || {}; //etc
}
}
test.prototype.methodName = function (){} //...etc
関数定義で何が起こっているか; 外側に 1 回、内側に 1 回宣言されます。このアプローチの価値は何ですか?
私はJavaScriptでこのパターンを見てきました:
var test = function () {
function test(args) {
this.properties = args || {}; //etc
}
}
test.prototype.methodName = function (){} //...etc
関数定義で何が起こっているか; 外側に 1 回、内側に 1 回宣言されます。このアプローチの価値は何ですか?
ここで最初に理解しておくべきことは、JavaScript の関数は新しいスコープを作成するということです。ブロック スコープは (まだ) ありません。したがって、別の関数内で宣言されたすべての変数または関数は、外部からは見えません。
それを念頭に置いてください: 外側の関数と同じ名前で内側の関数を定義すると、内側の関数が「引き継ぐ」(または「シャドウ」する) ため、名前によって、それ自体から再帰的に外側の関数を呼び出すことができなくなります。その名前。両方の関数test
の内側では内側の関数を参照し、外側の関数の外側ではtest
常に外側の関数を参照します。
変更している関数定義の後、(外側のもの) がコンストラクターとして使用されるとtest.prototype
想定できます。test
この場合、インナーtest
はコンストラクターの「プライベート」メソッドと見なすことができ、コンストラクター内からのみ呼び出すことができます。関数内で関数をオブジェクト指向で使用する詳細な例については、James T's answerを参照してください。
これはスコープです。
変数を関数として定義すると、関数スコープが作成されます。
その関数はそのスコープ内で宣言されているため、その関数内で同じ名前を宣言できます...わかりやすい例を見てください。
var User = function()
{
function PrivateToScope()
{
// A Function Only Accessible Inside This Function
alert( "private" );
}
return
{
PublicToScope: function()
{
// A Function Accessible From Outside This Function
alert( "public" );
}
}
}
var James = new User();
James.PublicToScope(); // Will alert "public"
James.PrivateToScope(); // Will fail to do anything
答えを説明するために、ユーザーはスコープを設定します。上記のように関数を同じ名前で宣言するため、問題ありません。
人々は私がこれを言うのを好まないのですが、このアプローチを他の言語のクラスであるかのように考えることができます。
var User = function()
{
}
のようなものです
class User
{
}
var User = function()
{
function Something()
{
}
}
のようなものです
class User
{
private function Something()
{
}
}
そして最後に
var User = function()
{
this.Something = function()
{
}
// or
return {
Something: function(){}
}
}
のようなものです
class User
{
public function Something()
{
}
}
範囲についてはすべてです。関数として宣言されたユーザー変数があり、人々が彼の姓と名を取得できるようにしたい場合、これらの変数または関数を「パブリック」として宣言します...しかし、彼の食事が良かったことを知りたい場合はどうなりますか?または悪い、それを解決するためのいくつかの複雑な関数があるかもしれませんが、良いか悪いかを知りたい..醜いことをするこれらすべての関数を非公開にして、パブリック関数で結果を表示するだけです。 ..
var User = function()
{
function CalculateDiet()
{
// Lots of scary diet calculating stuff comes out with the result
return result;
}
return
{
FirstName: "James",
LastName: "Poop",
StandardOfDiet: function()
{
return CalculateDiet();
}
}
}
var MyUser = new User();
alert( MyUser.FirstName );
alert( MyUser.StandardOfDiet() );
なんで気にするの?
それを定量化することは簡単で難しいですが、ここにいくつかの良いものがあります...
最後に、非常に異なる点として、テスト用のプロトタイプが添付されているので、ユーザー例でこれを実行してみましょう。ユーザーの配列があると想像してください。
var users = [
new User(),
new User()
];
これらを繰り返し処理して、通常のプロパティとメソッドをすべて取得できます。
for( a in users )
{
alert( users[ a ].FirstName );
}
しかし、私たちのアプリケーションで何かが起こったとしましょう...ユーザーが各ユーザーにフィッシュアンドチップスが好きかどうかを尋ねるボタンをクリックすると、ユーザーのための新しいメソッドが必要になります...すべての新しいメソッドをプロトタイプ化できます作成したその変数「user」の繰り返し...事前に宣言することもできますが、メモリを浪費し、将来のプログラマーを非常に具体的なものに基づくその存在で混乱させる可能性があります。
// user clicks button and runs this code
User.protoype.DoesUserLikeChips = function(){
// put some code in here that somehow makes this example make sense :)
}
これで、配列内のすべてのユーザーで、この新しいメソッドを呼び出すことができます... 新しい機能です。
なぜ users[ a ].DoesUserLikeChips = function(){} に行かないのでしょうか... 答えは、その 1 つのインスタンスだけに適用されるということです...
内部テスト関数は、private
外部テスト関数の関数です。そして、関数は外側のテスト関数の関数methodName
として設定されています。public
内部関数を外部関数と命名することに特別なことはありません。