4

私はJavaScriptでこのパターンを見てきました:

var test = function () {
    function test(args) {
       this.properties = args || {}; //etc
    }
}

test.prototype.methodName = function (){} //...etc

関数定義で何が起こっているか; 外側に 1 回、内側に 1 回宣言されます。このアプローチの価値は何ですか?

4

4 に答える 4

3

ここで最初に理解しておくべきことは、JavaScript の関数は新しいスコープを作成するということです。ブロック スコープは (まだ) ありません。したがって、別の関数内で宣言されたすべての変数または関数は、外部からは見えません。

それを念頭に置いてください: 外側の関数と同じ名前で内側の関数を定義すると、内側の関数が「引き継ぐ」(または「シャドウ」する) ため、名前によって、それ自体から再帰的に外側の関数を呼び出すことができなくなります。その名前。両方の関数testの内側では内側の関数を参照し、外側の関数の外側ではtest 常に外側の関数を参照します。

変更している関数定義の後、(外側のもの) がコンストラクターとして使用されるとtest.prototype想定できます。testこの場合、インナーtestはコンストラクターの「プライベート」メソッドと見なすことができ、コンストラクター内からのみ呼び出すことができます。関数内で関数をオブジェクト指向で使用する詳細な例については、James T's answerを参照してください。

于 2013-09-12T20:50:47.007 に答える
1

これはスコープです。

変数を関数として定義すると、関数スコープが作成されます。

その関数はそのスコープ内で宣言されているため、その関数内で同じ名前を宣言できます...わかりやすい例を見てください。

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 つのインスタンスだけに適用されるということです...

于 2013-09-12T20:56:16.127 に答える
0

内部テスト関数は、private外部テスト関数の関数です。そして、関数は外側のテスト関数の関数methodNameとして設定されています。public内部関数を外部関数と命名することに特別なことはありません。

于 2013-09-12T20:50:21.583 に答える