2012-11-19 14 views
6

Ok I shouldこれについての回答を知っていますが、何らかの理由で私は本当に理解していないか、JavaScriptを実際に知る必要がありませんでした。基本的なJavaScript OO

私の質問は以下のコードサンプルを見るとわかりました。わかりましたか、いくつかの情報がありません。


サンプル1

インスタンスごとに作成されIsOld方法、及びIsOld機能の別のコピーを使用するために関数(またはクラス)をインスタンス化する必要があります。

function MyClass1() { 
    this.IsOld = function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }; 
} 

// sample usage 
var m1 = new MyClass1(); 
console.log(m1.IsOld(34)); 

サンプル2

はインスタンス化する必要がありますがMyClass1とは異なり、スクリプトエンジンは、各クラスのインスタンスのための方法IsOldのコピーを作成する必要はありません。

var MyClass2 = (function() { 
    function MyClass2() { } 

    MyClass2.prototype.IsOld = function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }; 

    return MyClass2; 
})(); 

// sample usage 
var m2 = new MyClass2(); 
console.log(m2.IsOld(34)); 

サンプル3

IsOldメソッドにアクセスするための関数/クラスをインスタンス化する必要はありません。すべての呼び出しでIsOldメソッドの1つのインスタンスが使用されます。

var MyClass3 = { 
    IsOld: function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }, 
}; 

// sample uage 
console.log(MyClass3.IsOld(34)); 

注:私はSOのが、私は実際に私には意味を成していたものを見つけることができなかったいくつかの理由で、ここで同様の質問/回答のたくさんがあります推測しています。

+1

あなた第2の例は即座の関数式IMOと不必要に複雑であるが、理解は正しい。 –

+0

@FelixKling:これはCoffeeScriptがクラスをコンパイルする方法です:http://coffeescript.org/#try:class%20Auto – Amberlamps

答えて

2

あなたのご理解は正しいと思われます。

「インスタンス化する必要がある」とは、「新しい」キーワードの使用を意味する場合は、ここに何か追加したいと思います。

JavaScriptでは、新しいキーワードを使用することは、新しいインスタンスを作成する唯一の方法ではありません。 (コメントごとに編集) そして、どの関数もコンストラクタ関数として動作することができます。

あなたが任意の関数に続いて「新しい」キーワードを使用する場合(「X」と言う)何それがないこと

  1. は(「Y」と言う)新しいオブジェクトを作成し、新規として関数xのプロトタイプを設定されていますオブジェクト(y)のプロトタイプ。
  2. 新しく作成したオブジェクトyのコンテキストで関数 'x'を呼び出します。つまり、関数 'x'内のこの新しいオブジェクト 'y'を参照します。
  3. 関数がオブジェクトを返さない場合は、新しい式の結果として新しい演算子によって作成された 'x'。ここで

あなたは、メモリ(あなたがする必要があります)、コンストラクタ関数を使用して、追加を懸念している場合は、(http://javascript.crockford.com/

だから、ダグラス・クロックフォードでJavaScriptを学ぶための良い源であるすべての

これらのメソッドはすべて、この関数を使用して作成されたすべてのオブジェクトにコンストラクタとして継承されます。述べたように、私はサンプル2をシンプルにすることができると思う前に、しかし、:すべての提示例のために、すべてのインスタンス:

var MyClass2 = function MyClass2() { }; 

MyClass2.prototype.IsOld = function (age) { 
    if (age > 40) { 
     return true; 
    } 
    return false; 
}; 

var obj = new MyClass2(); 
+1

新しいキーワードは、ここで使用された場合はオプションではありません。 – nnnnnn

+0

はい、私は同意します。これらの機能はそれらの内部にオブジェクトを作成していないためです。私が言いたいことは、新しいオブジェクトを作成するために必須ではないということです。 – BuddhiP

1

私が知る限り、あなたはすべての3つのケースで正しいです。

  1. IsOldをインスタンス化する必要があり、すべてのインスタンスに対して新しい関数が作成されます。
  2. IsOldをそのままプロトタイプにインスタンス化する必要はありません。
  3. MyClass3はすでにインスタンス(関数ではないオブジェクト)であるため、IsOldをインスタンス化する必要はありません。
1

クラスの構造とJavascriptの動的な性質にに関するいくつかの誤解があっただ私には思えます「クラス」の新しい名前のない関数が作成されます。

あなたは(C++やJavaなど)より伝統的な方法で、 "クラス" を宣言したい場合は、あなたがより良いと思います:

1)の機能を定義します。

function MyClass_IsOld(age) { 
    return (age > 40); 
} 

2)を作成します"クラス" とそのプロトタイプ定義:

function MyClass() { /* put any instance constructor logic here */ }; 
MyClass.prototype.IsOld = MyClass_IsOld; 

3)は、クラスを使用します。

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37)); 

あなたは、通常の関数としての「メソッド」を使用ように、グローバルに宣言したい場合:あなたは実装の詳細を非表示にする場合

function MyClass_IsOld(age) { 
    return (age > 40); 
} 
function MyClass() { /* put any instance constructor logic here */ }; 
MyClass.prototype.IsOld = MyClass_IsOld; 

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37));  // use as a method 
console.log(MyClass_IsOld(37));   // use as a function 

、クロージャを作成します。

var MyClass = (function() { 
    function _MyClass_IsOld(age) { 
     return (age > 40); 
    } 
    function _MyClass() { /* put any instance constructor logic here */ }; 
    _MyClass.prototype.IsOld = _MyClass_IsOld; // use as a method 

    return _MyClass; 
})(); 

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37));  // use as a method 
console.log(MyClass_IsOld(37));   // ERROR: undefined function 
+0

_ "というように、2番目の例では、作成されたインスタンスごとにプロトタイプが上書きされます。" - いいえ、 'MyClass2()'コンストラクタを返す直後に呼び出された関数式の中で1回作成されます。もう一度見てみてください... – nnnnnn

+0

はい、あなたは正しかった、@ nnnnnn、私はクラスのコンストラクタを見落とし、インスタンスコンストラクタと自分自身を混乱させました。これは、ところで、Javascriptでクラスを実装する方法です。 「ヘッドアップ」をありがとう。 –