814

違いは何ですか

var A = function () {
    this.x = function () {
        //do something
    };
};

var A = function () { };
A.prototype.x = function () {
    //do something
};
4

15 に答える 15

476

例は非常に異なる結果をもたらします。

違いを見る前に、次の点に注意してください。

  • コンストラクターのプロトタイプ[[Prototype]]は、インスタンスのプライベートプロパティを介してインスタンス間でメソッドと値を共有する方法を提供します。
  • 関数のthisは、関数の呼び出し方法またはbindの使用によって設定されます(ここでは説明しません)。関数がオブジェクトで呼び出される場合 (例: myObj.method()) 、メソッド内のthisはオブジェクトを参照します。これが呼び出しまたはbindの使用によって設定されていない場合、デフォルトでグローバル オブジェクト (ブラウザのウィンドウ) または厳密モードでは未定義のままになります。
  • JavaScript はオブジェクト指向言語です。つまり、関数を含むほとんどの値はオブジェクトです。(文字列、数値、ブール値はオブジェクトではありません。)

問題のスニペットは次のとおりです。

var A = function () {
    this.x = function () {
        //do something
    };
};

この場合、変数Aには、関数への参照である値が割り当てられます。その関数が using を使用して呼び出されるとA()、関数のthisは呼び出しによって設定されないため、デフォルトでグローバル オブジェクトになり、式this.xは effective になりwindow.xます。その結果、右辺の関数式への参照が に代入されwindow.xます。

の場合:

var A = function () { };
A.prototype.x = function () {
    //do something
};

非常に異なる何かが発生します。最初の行では、変数Aに関数への参照が割り当てられます。JavaScript では、すべての関数オブジェクトにデフォルトでプロトタイププロパティがあるため、 A.prototypeオブジェクトを作成する別のコードはありません。

2 行目では、A.prototype.xに関数への参照が割り当てられています。これにより、存在しない場合はxプロパティが作成され、存在する場合は新しい値が割り当てられます。したがって、オブジェクトのxプロパティが式に含まれる最初の例との違い。

別の例を以下に示します。それは最初のものと似ています(そしておそらくあなたが尋ねようとしていたものです):

var A = new function () {
    this.x = function () {
        //do something
    };
};

この例ではnew、関数がコンストラクターとして呼び出されるように、関数式の前に演算子が追加されています。で呼び出されるとnew、関数のthisは、コンストラクターのパブリックプロトタイプを参照するように設定されたプライベート[[Prototype]]プロパティを持つ新しいオブジェクトを参照するように設定されます。したがって、割り当てステートメントでは、この新しいオブジェクトにプロパティが作成されます。コンストラクターとして呼び出されると、関数はデフォルトでthisオブジェクトを返すため、別のステートメントは必要ありません。xreturn this;

Axプロパティがあることを確認するには、次のようにします。

console.log(A.x) // function () {
                 //   //do something
                 // };

コンストラクターを参照する唯一の方法はA.constructorによるものであるため、これはnewの珍しい使用法です。次のようにする方がはるかに一般的です。

var A = function () {
    this.x = function () {
        //do something
    };
};
var a = new A();

同様の結果を達成する別の方法は、すぐに呼び出される関数式を使用することです。

var A = (function () {
    this.x = function () {
        //do something
    };
}());

この場合、A右辺に関数呼び出しの戻り値を代入します。ここでも、これは呼び出しで設定されていないため、グローバル オブジェクトを参照し、this.x有効になりwindow.xます。関数は何も返さないため、Aの値になりundefinedます。

これら 2 つのアプローチの違いは、Javascript オブジェクトを JSON との間でシリアル化および逆シリアル化する場合にも現れます。オブジェクトのプロトタイプで定義されたメソッドは、オブジェクトをシリアル化するときにシリアル化されません。これは、たとえば、オブジェクトのメソッドではなくデータ部分だけをシリアル化したい場合に便利です。

var A = function () { 
    this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance)); 
// {"objectsOwnProperties":"are serialized"} 

関連する質問:

補足: 2 つのアプローチ間で大幅なメモリ節約はないかもしれませんが、プロトタイプを使用してメソッドとプロパティを共有すると、各インスタンスが独自のコピーを持つよりもメモリ使用量が少なくなる可能性があります。

JavaScript は低水準言語ではありません。プロトタイピングやその他の継承パターンを、メモリの割り当て方法を明示的に変更する方法と考えるのはあまり価値がないかもしれません。

于 2008-11-22T05:26:52.203 に答える
242

他の人が最初のバージョンで言ったように、「this」を使用すると、クラス A のすべてのインスタンスが関数メソッド「x」の独自の独立したコピーを持つことになります。一方、「prototype」を使用すると、クラス A の各インスタンスがメソッド「x」の同じコピーを使用することになります。

この微妙な違いを示すコードを次に示します。

// x is a method assigned to the object using "this"
var A = function () {
    this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
    this.x = function() { alert( value ); }
};

var a1 = new A();
var a2 = new A();
a1.x();  // Displays 'A'
a2.x();  // Also displays 'A'
a1.updateX('Z');
a1.x();  // Displays 'Z'
a2.x();  // Still displays 'A'

// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };

B.prototype.updateX = function( value ) {
    B.prototype.x = function() { alert( value ); }
}

var b1 = new B();
var b2 = new B();
b1.x();  // Displays 'B'
b2.x();  // Also displays 'B'
b1.updateX('Y');
b1.x();  // Displays 'Y'
b2.x();  // Also displays 'Y' because by using prototype we have changed it for all instances

他の人が述べたように、いずれかの方法を選択する理由はさまざまです。私のサンプルは、違いを明確に示すためのものです。

于 2008-11-22T05:41:49.443 に答える
168

次の 2 つの例を見てください。

var A = function() { this.hey = function() { alert('from A') } };

対。

var A = function() {}
A.prototype.hey = function() { alert('from prototype') };

ここにいるほとんどの人 (特に評価の高い回答) は、理由を説明せずに、どのように違うのかを説明しようとしました。私はこれは間違っていると思います。まず基本を理解すれば、その違いは明白になります。まずは基本的なことから説明していきましょう...

a) 関数は JavaScript のオブジェクトです。JavaScript のすべてのオブジェクトは、内部プロパティを取得します (つまり、Chrome などのブラウザーを除いて、他のプロパティのようにアクセスすることはできません)。これは、しばしば参照され__proto__ます (Chrome で実際に入力anyObject.__proto__して、それが参照するものを確認できます。これはまさにそれです) , プロパティ, それ以上. JavaScript のプロパティ = オブジェクト内の変数.

では、この__proto__プロパティは何を指しているのでしょうか? 通常は別のオブジェクトです (理由は後で説明します)。プロパティの JavaScript が__proto__別のオブジェクトを指さないようにする唯一の方法は、 を使用することvar newObj = Object.create(null)です。これを行っても__proto__、プロパティはオブジェクトのプロパティとしてまだ存在しますが、別のオブジェクトを指しているのではなく、 を指していnullます。

ここで、ほとんどの人が混乱します。

JavaScript で新しい関数を作成すると (これもオブジェクトですよね?)、それが定義された瞬間に、JavaScript はその関数に という新しいプロパティを自動的に作成しますprototype。それを試してみてください:

var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined

A.prototypeプロパティとはまったく異なり__proto__ます。この例では、'A' には 'prototype' と と呼ばれる 2 つのプロパティがあり__proto__ます。これは人々にとって大きな混乱です。prototypeプロパティはまったく関係がなく、__proto__別々の値を指す別々のものです。

__proto__疑問に思われるかもしれません: JavaScript では、すべてのオブジェクトにプロパティが作成されるのはなぜですか? そうですね、一言: delegation。オブジェクトのプロパティを呼び出し、そのオブジェクトにそれがない場合、JavaScript は によって参照されているオブジェクトを探して、それがある__proto__かどうかを確認します。それがない場合は__proto__、チェーンが終了するまで、そのオブジェクトのプロパティなどを調べます。したがって、プロトタイプ チェーンという名前が付けられます。もちろん、__proto__がオブジェクトを指しておらず、代わりに を指している場合null、幸運にも、JavaScript はそれを認識し、undefinedそのプロパティを返します。

prototypeまた、関数を定義するときに、JavaScript が関数に対して呼び出されるプロパティを作成するのはなぜでしょうか? それはあなたをだまそうとするので、クラスベースの言語のように動作することをだまします。

例を続けて、から「オブジェクト」を作成しましょうA

var a1 = new A();

これが起こったとき、バックグラウンドで何かが起こっています。a1新しい空のオブジェクトが割り当てられた通常の変数です。

new関数呼び出しの前に演算子を使用したという事実A()は、バックグラウンドで追加の何かを行いました。newキーワードは、現在参照している新しいオブジェクトを作成しましたが、そのa1オブジェクトは空です。さらに何が起こっているかは次のとおりです。

各関数定義には、 created?という新しいプロパティが作成されprototypeます (プロパティとは異なり、アクセスできます)。__proto__さて、そのプロパティは現在使用されています。

これで、焼きたての空のa1オブジェクトができあがりました。JavaScript のすべてのオブジェクトには、それが null であるか別のオブジェクトであるかにかかわらず、__proto__何かを指す (それも持つ) 内部プロパティがあると述べました。オペレーターが行うことは、関数のプロパティを指すようにそのプロパティを設定するa1ことです。それをもう一度読んでください。それは基本的にこれです:new__proto__prototype

a1.__proto__ = A.prototype;

これは空のオブジェクトにすぎないと言いましたA.prototype( を定義する前に別のものに変更しない限りa1)。つまり、基本的a1.__proto__に同じものA.prototypeを指すようになりました。つまり、空のオブジェクトです。どちらも、この行が発生したときに作成された同じオブジェクトを指しています。

A = function() {} // JS: cool. let's also create A.prototype pointing to empty {}

var a1 = new A()ここで、ステートメントが処理されるときに別のことが起こっています。基本的A()に実行され、 A が次のような場合:

var A = function() { this.hey = function() { alert('from A') } };

内部のものfunction() { }はすべて実行されます。this.hey..行に到達すると、thisに変更され、次のようにa1なります。

a1.hey = function() { alert('from A') }

this変更の理由については説明しませんa1が、これは詳細を学ぶための優れた回答です。

要約するとvar a1 = new A()、バックグラウンドで 3 つの処理が行われます。

  1. まったく新しい空のオブジェクトが作成され、 に割り当てられa1ます。a1 = {}
  2. a1.__proto__プロパティは、ポイントと同じものをA.prototype指すように割り当てられます (別の空のオブジェクト {} )

  3. 関数は、ステップ 1 で作成された新しい空のオブジェクトに設定さA()れて実行されています (変更の理由については、上記の回答を参照してください) 。thisthisa1

それでは、別のオブジェクトを作成してみましょう。

var a2 = new A();

手順 1、2、3 が繰り返されます。何か気づきましたか?キーワードはリピートです。ステップ 1:a2新しい空のオブジェクトになります。ステップ 2: その__proto__プロパティは同じものA.prototypeを指し、最も重要なことは、ステップ 3: 関数A()が再度実行されることです。つまり、関数を含むプロパティa2が取得されます。2 つのSEPARATE 関数を指す名前の 2 つの SEPARATE プロパティがあります。同じことを行う同じ 2 つの異なるオブジェクトに重複した関数があります。おっと... で作成された 1000 個のオブジェクトがある場合、これのメモリへの影響を想像できます。すべての関数宣言は、2 のようなものよりも多くのメモリを消費します。どうすればこれを防ぐことができますか?heya1a2heynew A

__proto__プロパティがすべてのオブジェクトに存在する理由を覚えていますか? そのため、 (存在しない)のyoManプロパティを取得すると、そのプロパティが参照され、それがオブジェクトである場合 (ほとんどの場合そうです)、 が含まれているかどうかがチェックされ、含まれていない場合は、そのオブジェクトなどを参照します。そうであれば、そのプロパティ値を取得して表示します。a1__proto__yoMan__proto__

したがって、誰かがこの事実 + を作成するときにa1、その__proto__プロパティが同じ (空の) オブジェクトA.prototypeを指しているという事実を使用して、これを行うことにしました。

var A = function() {}
A.prototype.hey = function() { alert('from prototype') };

涼しい!を作成するa1と、再び上記の 3 つの手順がすべて実行されます。手順 3 では、function A()実行するものが何もないため、何もしません。もしそうなら:

a1.hey

が含まれてa1いないheyことを確認し、その__proto__プロパティ オブジェクトをチェックして、それが含まれているかどうかを確認します。

このアプローチでは、新しいオブジェクトの作成ごとに関数が複製されるステップ 3 の部分を排除します。a1個別のプロパティをa2持つ代わりにhey、今ではどれもそれを持っていません。それは、あなたは今では自分で理解したと思います。それは良いことです... 理解できれば__proto__Function.prototypeこれらのような質問はかなり明白になります.

注: 一部の人々は、内部の Prototype プロパティを と呼ばない傾向があります__proto__。私はこの名前を投稿を通じて使用して、Functional.prototypeプロパティに対して 2 つの異なるものとして明確に区別しました。

于 2016-01-22T13:47:10.783 に答える
60

ほとんどの場合、それらは本質的に同じですが、オブジェクトごとに個別の関数ではなく、関数のインスタンスが 1 つしかないため、2 番目のバージョンではメモリが節約されます。

最初のフォームを使用する理由は、「プライベート メンバー」にアクセスするためです。例えば:

var A = function () {
    var private_var = ...;

    this.x = function () {
        return private_var;
    };

    this.setX = function (new_x) {
        private_var = new_x;
    };
};

JavaScript のスコープ規則により、private_var は this.x に割り当てられた関数で使用できますが、オブジェクトの外部では使用できません。

于 2008-11-22T05:03:58.570 に答える
28

最初の例は、そのオブジェクトのインターフェースのみを変更します。2 番目の例では、そのクラスのすべてのオブジェクトのインターフェイスを変更します。

于 2008-11-22T04:43:28.000 に答える
21

this代わりに使用することの究極の問題prototypeは、メソッドをオーバーライドするときに、基本クラスのコンストラクターがオーバーライドされたメソッドを引き続き参照することです。このことを考慮:

BaseClass = function() {
    var text = null;

    this.setText = function(value) {
        text = value + " BaseClass!";
    };

    this.getText = function() {
        return text;
    };

    this.setText("Hello"); // This always calls BaseClass.setText()
};

SubClass = function() {
    // setText is not overridden yet,
    // so the constructor calls the superclass' method
    BaseClass.call(this);

    // Keeping a reference to the superclass' method
    var super_setText = this.setText;
    // Overriding
    this.setText = function(value) {
        super_setText.call(this, "SubClass says: " + value);
    };
};
SubClass.prototype = new BaseClass();

var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!

subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!

対:

BaseClass = function() {
    this.setText("Hello"); // This calls the overridden method
};

BaseClass.prototype.setText = function(value) {
    this.text = value + " BaseClass!";
};

BaseClass.prototype.getText = function() {
    return this.text;
};

SubClass = function() {
    // setText is already overridden, so this works as expected
    BaseClass.call(this);
};
SubClass.prototype = new BaseClass();

SubClass.prototype.setText = function(value) {
    BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};

var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!

これが問題ではないと思われる場合は、プライベート変数なしで生活できるかどうか、およびリークが発生したときにそれを知るのに十分な経験があるかどうかに依存します。また、メソッド定義の後にコンストラクタ ロジックを配置する必要があるのは不便です。

var A = function (param1) {
    var privateVar = null; // Private variable

    // Calling this.setPrivateVar(param1) here would be an error

    this.setPrivateVar = function (value) {
        privateVar = value;
        console.log("setPrivateVar value set to: " + value);

        // param1 is still here, possible memory leak
        console.log("setPrivateVar has param1: " + param1);
    };

    // The constructor logic starts here possibly after
    // many lines of code that define methods

    this.setPrivateVar(param1); // This is valid
};

var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0

a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0

対:

var A = function (param1) {
    this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
    this.publicVar = value; // No private variable
};

var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1
于 2012-09-21T11:15:27.407 に答える
21

すべてのオブジェクトは、プロトタイプ オブジェクトにリンクされています。存在しないプロパティにアクセスしようとすると、JavaScript はオブジェクトのプロトタイプ オブジェクトでそのプロパティを検索し、存在する場合はそれを返します。

関数コンストラクターのprototypeプロパティは、 を使用するときにその関数で作成されたすべてのインスタンスのプロトタイプ オブジェクトを参照しますnew


x最初の例では、関数で作成された各インスタンスにプロパティを追加していAます。

var A = function () {
    this.x = function () {
        //do something
    };
};

var a = new A();    // constructor function gets executed
                    // newly created object gets an 'x' property
                    // which is a function
a.x();              // and can be called like this

2 番目の例では、 で作成されたすべてのインスタンスがA指すプロトタイプ オブジェクトにプロパティを追加しています。

var A = function () { };
A.prototype.x = function () {
    //do something
};

var a = new A();    // constructor function gets executed
                    // which does nothing in this example

a.x();              // you are trying to access the 'x' property of an instance of 'A'
                    // which does not exist
                    // so JavaScript looks for that property in the prototype object
                    // that was defined using the 'prototype' property of the constructor

結論として、最初の例では、関数のコピーが各インスタンスに割り当てられます。2 番目の例では、関数の 1 つのコピーがすべてのインスタンスで共有されます

于 2016-02-11T15:30:41.917 に答える
16

私はこれが死ぬまで答えられたことを知っていますが、速度の違いの実際の例を示したいと思います.

オブジェクトに直接関数:

function ExampleFn() {
    this.print = function() {
        console.log("Calling print! ");
    }
}

var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
    objects.push(new ExampleFn());
}
console.timeEnd('x');

//x: 1151.960693359375ms

プロトタイプの機能:

function ExampleFn() {
}
ExampleFn.prototype.print = function() {
    console.log("Calling print!");
}

var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
    objects.push(new ExampleFn());
}
console.timeEnd('y');

//x: 617.866943359375ms

ここではprint、Chrome のメソッドを使用して 2,000,000 個の新しいオブジェクトを作成しています。すべてのオブジェクトを配列に格納しています。プロトタイプprintの装着には、約 1/2 の時間がかかります。

于 2017-07-28T20:56:22.830 に答える
14

私が JavaScript トレーニング コースで学んだ、より包括的な回答をご紹介しましょう。

ほとんどの回答は、すでに違いについて言及しています。つまり、プロトタイプを作成するとき、関数はすべての(将来の)インスタンスと共有されます。クラスで関数を宣言すると、インスタンスごとにコピーが作成されます。

一般に、正しいか間違っているということはありません。それは好みの問題か、要件に応じた設計上の決定です。ただし、プロトタイプは、この回答の最後でわかるように、オブジェクト指向の方法で開発するために使用される手法です。

質問で2つのパターンを示しました。さらに2つ説明し、関連する場合は違いを説明しようとします. 自由に編集/拡張してください。すべての例で、場所を持ち、移動できる車のオブジェクトに関するものです。

オブジェクト デコレータ パターン

このパターンが現在でも有効かどうかはわかりませんが、存在します。そして、それについて知ることは良いことです。オブジェクトとプロパティをデコレータ関数に渡すだけです。デコレーターは、プロパティとメソッドを含むオブジェクトを返します。

var carlike = function(obj, loc) {
    obj.loc = loc;
    obj.move = function() {
        obj.loc++;
    };
    return obj;
};

var amy = carlike({}, 1);
amy.move();
var ben = carlike({}, 9);
ben.move();

機能クラス

JavaScript の関数は特殊なオブジェクトです。関数は、呼び出されるだけでなく、他のオブジェクトと同様にプロパティを格納できます。

この場合Carは、慣れ親しんだ方法で呼び出すことができる関数( objectと考えます) です。プロパティ(関数を持つオブジェクト)があります。が呼び出されると関数が呼び出され、魔法のように機能し、 内で定義されたメソッドで関数 (オブジェクトと考えてください) を拡張します。methodsmoveCarextendCarmethods

この例は異なりますが、質問の最初の例に最も近いものです。

var Car = function(loc) {
    var obj = {loc: loc};
    extend(obj, Car.methods);
    return obj;
};

Car.methods = {
    move : function() {
        this.loc++;
    }
};

var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();

プロトタイプクラス

最初の 2 つのパターンでは、手法を使用して共有メソッドを定義する方法、またはコンストラクターの本体でインラインで定義されたメソッドを使用する方法について説明できます。どちらの場合も、すべてのインスタンスに独自のmove機能があります。

プロトタイプ委譲による機能共有がプロトタイプパターンのまさに目標であるため、プロトタイプパターンは同じ調査にはあまり適していません。他の人が指摘したように、より良いメモリフットプリントを持つことが期待されています。

ただし、知っておくと興味深い点が 1 つあります。すべてのオブジェクトには、関連付けられた関数 (オブジェクトと考えてください) を指すprototype便利なプロパティがあります。constructor

最後の3行について:

この例では、それ自体に経由してリンクCarするprototypeオブジェクトにリンクします。つまり、それ自体です。これにより、特定のオブジェクトを作成したコンストラクター関数を特定できます。constructorCarCar.prototype.constructorCar

amy.constructorのルックアップが失敗したためCar.prototype、コンストラクター プロパティを持つ に委譲されます。そしてそうamy.constructorですCar

さらに、amyですinstanceof Car。このinstanceof演算子は、右側のオペランドのプロトタイプ オブジェクト ( ) が左側のオペランドのプロトタイプ ( ) チェーンCarのどこかにあるかどうかを調べることによって機能します。amy

var Car = function(loc) {
    var obj = Object.create(Car.prototype);
    obj.loc = loc;
    return obj;
};

Car.prototype.move = function() {
        this.loc++;
};

var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();

console.log(Car.prototype.constructor);
console.log(amy.constructor);
console.log(amy instanceof Car);

一部の開発者は、最初は混乱する可能性があります。以下の例を参照してください。

var Dog = function() {
  return {legs: 4, bark: alert};
};

var fido = Dog();
console.log(fido instanceof Dog);

のプロトタイプがのプロトタイプ チェーンのどこにも見つからないため、instanceof演算子は を返します。は、オブジェクト リテラルで作成される単純なオブジェクトです。つまり、単に に委譲します。falseDogfidofidoObject.prototype

疑似古典パターン

これは実際には単純化された形式のプロトタイプ パターンの別の形式であり、newコンストラクターを使用するため、たとえば Java でプログラミングする人にとってはよりなじみ深いものです。

これは、実際にはプロトタイプ パターンと同じことを行います。これは、プロトタイプ パターンの単なる構文糖衣です。

ただし、主な違いは、疑似古典的パターンを使用する場合にのみ適用される JavaScript エンジンに実装された最適化があることです。疑似古典的パターンは、プロトタイプ パターンのおそらくより高速なバージョンであると考えてください。両方の例のオブジェクトの関係は同じです。

var Car = function(loc) {
    this.loc = loc;
};

Car.prototype.move = function() {
        this.loc++;
};

var amy = new Car(1);
amy.move();
var ben = new Car(9);
ben.move();

最後に、オブジェクト指向プログラミングがどのように行われるかを理解することはそれほど難しくありません。2 つのセクションがあります。

プロトタイプ (チェーン) で共通のプロパティ/メソッドを定義する 1 つのセクション。

そして、オブジェクトを互いに区別する定義を配置する別のセクション (loc例の variable )。

これにより、JavaScript でスーパークラスやサブクラスなどの概念を適用できるようになります。

自由に追加・編集してください。もう一度完成したら、これをコミュニティ wiki にすることができます。

于 2015-05-10T07:42:58.787 に答える
14

プロトタイプはクラスのテンプレートです。これは、それの将来のすべてのインスタンスに適用されます。これはオブジェクトの特定のインスタンスです。

于 2008-11-22T06:16:02.543 に答える
11

@Matthew Crumley が正しいと思います。それらは、構造的にではなくても、機能的には同等です。を使用して作成されたオブジェクトを Firebug を使用して調べると、newそれらが同じであることがわかります。ただし、私の好みは次のとおりです。C#/Java で慣れ親しんだものに似ていると思います。つまり、クラスを定義し、フィールド、コンストラクター、およびメソッドを定義します。

var A = function() {};
A.prototype = {
    _instance_var: 0,

    initialize: function(v) { this._instance_var = v; },

    x: function() {  alert(this._instance_var); }
};

編集変数のスコープがプライベートであることを意味するつもりはありませんでした.javascriptでクラスを定義する方法を説明しようとしていました. これを反映するために変数名が変更されました。

于 2008-11-22T05:11:46.680 に答える
10

他の回答で説明したように、プロトタイプの関数は、インスタンス化ごとに作成される関数ではなく、すべてのインスタンス化で共有されるため、実際にはパフォーマンスに関する考慮事項です。

これを示すためにjsperfをまとめました。クラスのインスタンス化にかかる時間には劇的な違いがありますが、実際には多くのインスタンスを作成している場合にのみ関係があります.

http://jsperf.com/functions-in-constructor-vs-prototype

于 2014-08-14T18:18:30.073 に答える