次の2つの宣言の違いは何ですか?
Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }
最初のステートメントを静的メソッドの宣言として、2番目のステートメントをインスタンスメソッドの宣言として考えても大丈夫ですか?
はい、最初の関数はその コンストラクタ関数 のオブジェクトインスタンスとは関係がありません。 'staticのように考えることができます。方法'。
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
& JS Bin
から生成された結果
上のjsbinリンクをクリックしてコードをステップスルーしてください。
コメント付きセクションを切り替える ctrl+/
はい、最初のものは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はクラスレス言語のままです。 ES6で導入されたclass
は、主に既存のプロトタイプベースの継承モデルに対する構文上の糖です。