回答:
はい、最初の関数はそのコンストラクター関数のオブジェクトインスタンスとは関係ありません。「静的メソッド」のように考えることができます。
JavaScriptでは、関数はファーストクラスのオブジェクトです。つまり、他のオブジェクトと同じように扱うことができます。この場合、関数オブジェクトにプロパティを追加するだけです。
2番目の関数は、コンストラクター関数プロトタイプを拡張しているため、new
キーワードで作成されたすべてのオブジェクトインスタンスで使用でき、その関数内のコンテキスト(this
キーワード)は、それを呼び出す実際のオブジェクトインスタンスを参照します。
この例を考えてみましょう:
// constructor function
function MyClass () {
var privateVariable; // private member only available within the constructor fn
this.privilegedMethod = function () { // it can access private members
//..
};
}
// A 'static method', it's just like a normal function
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};
MyClass.prototype.publicMethod = function () {
// the 'this' keyword refers to the object instance
// you can access only 'privileged' and 'public' members
};
var myObj = new MyClass(); // new object instance
myObj.publicMethod();
MyClass.staticMethod();
MyClassの複数のインスタンスを作成しても、メモリにはpublicMethodのインスタンスが1つしかありませんが、privilegedMethodの場合、多くのインスタンスが作成され、staticMethodはオブジェクトインスタンスと関係がありません。
これが、プロトタイプがメモリを節約する理由です。
また、親オブジェクトのプロパティを変更した場合、子の対応するプロパティが変更されていない場合は、更新されます。
視覚的な学習者の場合、関数を定義せずに .prototype
ExampleClass = function(){};
ExampleClass.method = function(customString){
console.log((customString !== undefined)?
customString :
"called from func def.");}
ExampleClass.method(); // >> output: `called from func def.`
var someInstance = new ExampleClass();
someInstance.method('Called from instance');
// >> error! `someInstance.method is not a function`
同じコードで、.prototype
追加された場合、
ExampleClass.prototype.method = function(customString){
console.log((customString !== undefined)?
customString :
"called from func def.");}
ExampleClass.method();
// > error! `ExampleClass.method is not a function.`
var someInstance = new ExampleClass();
someInstance.method('Called from instance');
// > output: `Called from instance`
より明確にするために
ExampleClass = function(){};
ExampleClass.directM = function(){} //M for method
ExampleClass.prototype.protoM = function(){}
var instanceOfExample = new ExampleClass();
ExampleClass.directM(); ✓ works
instanceOfExample.directM(); x Error!
ExampleClass.protoM(); x Error!
instanceOfExample.protoM(); ✓ works
****上記の例では、someInstance.method()は実行されません。ExampleClass.method()が
原因でエラーが発生し、実行を続行できません。
ただし、説明と理解を容易にするために、この順序を維持しました。****
生成された結果chrome developer console
&
上記のjsbinリンクをクリックして、コードをステップ実行します。+で
コメントセクションを切り替えJS Bin
ctrl/
はい、1つ目はとstatic method
も呼ばれclass method
、2つ目はinstance method
ます。
より詳細に理解するために、以下の例を検討してください。
ES5内
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.isPerson = function(obj) {
return obj.constructor === Person;
}
Person.prototype.sayHi = function() {
return "Hi " + this.firstName;
}
上記のコードでisPerson
は、は静的メソッドsayHi
ですが、のインスタンスメソッドですPerson
。
以下は、Person
コンストラクタからオブジェクトを作成する方法です。
var aminu = new Person("Aminu", "Abubakar");
静的メソッドを使用しますisPerson
。
Person.isPerson(aminu); // will return true
インスタンスメソッドを使用しますsayHi
。
aminu.sayHi(); // will return "Hi Aminu"
ES6内
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
static isPerson(obj) {
return obj.constructor === Person;
}
sayHi() {
return `Hi ${this.firstName}`;
}
}
static
静的メソッドを宣言するためにキーワードがどのように使用されたかを見てくださいisPerson
。
Person
クラスのオブジェクトを作成します。
const aminu = new Person("Aminu", "Abubakar");
静的メソッドを使用しますisPerson
。
Person.isPerson(aminu); // will return true
インスタンスメソッドを使用しますsayHi
。
aminu.sayHi(); // will return "Hi Aminu"
注:どちらの例も基本的に同じですが、JavaScriptはクラスレス言語のままです。class
で導入されたES6は、主に既存のプロトタイプベースの継承モデルを超える構文糖です。
obj.constructor === Person
いtrue
ます... クラスインスタンスのコンストラクタ===
はどのようにしてクラス自体を...できますか?(これは、セットのサブセットがセット自体であると言っているようなものです...)