6

わかりました。これに対する答えを知っている必要がありますが、何らかの理由で、JavaScriptを実際に理解したことがないか、実際に理解する必要がありました。

私の質問は次のとおりです。以下のコードサンプルを見ると、理解が正しいのでしょうか、それともいくつかの情報が不足しているのでしょうか。


サンプル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すべての呼び出しで使用されます。

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

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

注:SOには同様の質問/回答がたくさんあると思いますが、何らかの理由で実際に意味のあるものを見つけることができませんでした。

4

3 に答える 3

2

あなたの理解は正しいようです。

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

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

'new'キーワードの後に​​任意の関数(たとえば'x')を使用すると、その機能は次のようになります。

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

Douglas Crockford( http://javascript.crockford.com/)によるJavaScriptを学ぶための良い情報源は次のとおりです。

したがって、メモリが気になる場合は(そうする必要があります)、コンストラクター関数を使用し、サンプル2で行ったように、すべての一般的なメソッドを関数プロトタイプに追加します。

次に、これらのメソッドはすべて、この関数をコンストラクターとして使用して作成されたすべてのオブジェクトに継承されます。ただし、前述のように、サンプル2の方が簡単だと思います。

var MyClass2 = function MyClass2() { };

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

var obj = new MyClass2();
于 2012-11-19T10:14:40.460 に答える
1

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

  1. インスタンス化する必要がIsOldあり、すべてのインスタンスに対して新しい関数が作成されます。
  2. IsOldプロトタイプのようにインスタンス化する必要はありません。
  3. IsOldMyClass3はすでにインスタンス(関数ではなくオブジェクト)であるため、インスタンス化する必要はありません。
于 2012-11-19T10:00:56.620 に答える
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
于 2012-11-19T10:50:28.060 に答える