財産とは何ですかprototype
、なぜそれが必要なのですか?prototype
これまでのところ、これにより、オブジェクトのより本質的でプライベートなものへのパブリックアクセスが提供されることを学びました。あれは正しいですか?
また、次のステートメントの違いは何ですか?
MyConstructor.age = 30;
MyConstructor.prototype.age = 30;
要するに、私はキーワードのより良い理解が必要ですprototype
。
ありがとう
財産とは何ですかprototype
、なぜそれが必要なのですか?prototype
これまでのところ、これにより、オブジェクトのより本質的でプライベートなものへのパブリックアクセスが提供されることを学びました。あれは正しいですか?
また、次のステートメントの違いは何ですか?
MyConstructor.age = 30;
MyConstructor.prototype.age = 30;
要するに、私はキーワードのより良い理解が必要ですprototype
。
ありがとう
「プロトタイプ」は、オブジェクトで役割を果たすものです。
Javascriptでは、すべてがオブジェクトです。すべてのオブジェクトには種類があり、したがってprototype
その種類を継承します。
たとえば、単純な配列を考えてみましょうvar a = []
。のように、それを使って操作を行うことができますa.push(10)
。このpush
方法はどこから来たのですか?Array
オブジェクトのプロトタイプからa
です。
Array
オブジェクトでメソッドを定義するだけで、オブジェクトに独自のメソッドを追加できますprototype
。例えば:
Array.prototype.sortNum = function() {this.sort(function(a, b) {return a - b});};
このようにして、メソッドを定義する前に作成された配列も含め、すべてのa.sortNum()
配列で同じようなことを行うことができます。sortNum
(注:互換性の理由から、通常、sのようなネイティブオブジェクトのプロトタイプを拡張することはお勧めしません。ただし、この特定の例は、通常、古いブラウザーのような正規化メソッドとArray
同様に、歓迎すべき追加です。)map
forEach
(決して拡張しないでください!ステートメント、演算子、およびこれらの種類のケースObject.prototype
を台無しにすることを気にしない限り。)for...in
in
名前MyConstructor
が示すように、独自のクラスprototype
を定義する場合は、そのクラスのすべてのインスタンスのメソッドを定義するために、そのクラスを定義する必要があります。
function MyConstructor(name) {this.name = name};
MyConstructor.prototype = {
print: function() {return this.name;}
};
var mc = new MyConstructor("foo");
alert(mc.print()); // alerts "foo"
prototype
sで関数だけでなく、次のように定義することもできます。
MyConstructor.prototype.age = 30;
alert(mc.age); // alerts 30
これを行って「デフォルト」のオブジェクト値を定義する場合は注意が必要です。これを変更すると、そのクラスのすべてのインスタンスが変更される可能性があるためです。
しかし、これは便利Object.defineProperty
です:
Object.defineProperty(MyConstructor.prototype, "wholeString", {
get: function() {return this.name + "=" + this.age;},
set: function(v) {this.name = v.substring(3);}
});
alert(mc.wholeString); // alerts "foo = 30"
(残念ながら、IE <9ではこれはDOMオブジェクトに対してのみ許可されます...)
代わりに定義する場合MyConstructor.age = 30
、実際に行っているのは関数 MyConstructor
のメンバーを定義することなので、mc.age
未定義になります。のすべてのインスタンスは、関数のものではなく、でMyConstructor
定義されたメソッドとメンバーを継承します。MyConstructor.prototype
MyConstructor
実際、言うことはもっとたくさんあります。オブジェクトは別のクラスのサブクラスである可能性があるためprototype
、スーパークラスのを継承することもできます。たとえばdocument.body
、はのインスタンスですHTMLBodyElement
。これは、のサブクラスでありHTMLElement
、のサブクラスでElement
あり、などのように、最上位のスーパークラスとして取得Object
されるまで続きます。したがって、、、、およびのプロトタイプでdocument.body
定義されたすべてのメソッドを継承します。これはプロトタイプチェーンと呼ばれます。HTMLBodyElement
HTMLElement
Element
Object
カスタムオブジェクトで同じことを行うのは少し注意が必要です。
function Class() {};
Class.prototype.foo = function() {alert("foo");};
function Subclass() {};
Subclass.prototype = new Class();
Subclass.prototype.bar = function() {alert("bar");};
var a = new Class(), b = new Subclass();
a.foo(); // alerts"foo"
a.bar(); // throws an error
b.foo(); // alerts "foo"
b.bar(); // alerts "bar"
a instanceof Class; // true
a instanceof Subclass; // false
b instanceof Class; // true
b instanceof Subclass; // true
JavaScriptでは、関数オブジェクトには組み込みの.prototype
プロパティがあります。このプロパティの値はオブジェクトです。関数がコンストラクターとして使用される場合、結果のインスタンスはその「プロトタイプ」オブジェクトから継承します。
例:
var Dog = function () {}; // the constructor function
Dog.prototype.bark = function () {}; // adding a method to Dog.prototype
var dog1 = new Dog; // creating a new instance
dog1.bark(); // the instance inherits the "bark" method from Dog.prototype
(関数オブジェクトの)プロパティは内部プロパティ.prototype
と同じではないことに注意してください。[[Prototype]]
すべてのオブジェクトには後者が含まれています。これは、オブジェクトのプロトタイプへの内部参照です。(上記の例では、dog1
オブジェクト[[Prototype]]
はを参照していDog.prototype
ます。)一方、組み込み.prototype
プロパティを持つのは関数オブジェクトのみです(コンストラクターとして使用できるのは関数オブジェクトのみであるため、これは理にかなっています)。
var foo = function () {};
foo.bar = 5;
foo.prototype.foobar = 10;
var x = new foo();
x.bar; // undefined
x.foobar; // 10
編集:また、あなたはそれからすることができます
foo.prototype.foobar = 20;
x.foobar; // 20