new 演算子は、ユーザー定義オブジェクト型のインスタンスか、コンストラクタを持つ組み込みオブジェクトのインスタンスを作成します。
new演算子は、実際にはコンストラクタと引数のセットを受け取り、インスタンスを生成します。これは次のようになります:
空の JavaScript オブジェクト {} を作成します;
ヌル・オブジェクトのプロトタイプ・ポインターは、コンストラクターのプロトタイプ・オブジェクトを指します;
関数の call メソッドを使用して this ポイントを変更し、空のオブジェクトにプロパティまたはメソッドをマウントします;
コンストラクタがreturnなしで呼ばれた場合、最初のステップで作成されたオブジェクトである thisを返します。
コンストラクタを使ってオブジェクトに属性を追加するこの方法は、構文的にはクラスとよく似ています。JavaScriptには、コンストラクタのprototype属性にプロパティを追加する別の方法もあります。
function constructor() {
}
constructor.prototype.p1 = 'p1'
constructor.prototype.p2 = function () {
console.log(this.p1)
}
var obj = new constructor
obj.p2() // 'p1'
これは、クラスベースのオブジェクト指向をシミュレートするための一般的な方法でした。
ありがたいことに、ES6のリリースにより、新しい+関数のアプローチを使ってクラスをモデリングする代わりに、classキーワードを使ってクラスを直接定義できるようになりました。
ES6 class
class キーワードは、オブジェクト・プロトタイプをより明確に、よりオブジェクト指向プログラミングの構文に近い形で記述できるように設計された構文上の砂糖のようなものです。その背後にあるロジックは、前述の new + 関数のアプローチとまったく同じです。
class Fun {
constructor(x, y) {
this.x = x
this.y = y
}
toString() {
return '(' + this.x + ', ' + this.y + ')'
}
}
var p = new Fun(1, 2)
p.x // 1
タンタンマウント
function Fun(x, y) {
this.x = x
this.y = y
}
Fun.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')'
};
var p = new Fun(1, 2)
p.x // 1
既存のクラス構文の中では、getter/setterとmethodを使用してクラスを作成するのが最も互換性があります。
つまり、ゲッターはgetとsetキーワードで作成し、メソッドは括弧と中括弧で作成し、データ型メンバはコンストラクタ内に記述します。
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
JavaScriptは論理的に、各クラスを共通のプロトタイプを持つオブジェクトの集合とみなし、クラスで定義されたメソッドやプロパティはプロトタイプオブジェクトの上に書かれます。さらに、クラスは継承する機能も提供します。
class Animal {
constructor(name) {
this.name = name
}
speak() {
console.log(this.name + ' makes a noise.')
}
}
class Dog extends Animal {
constructor(name) {
super(name)
}
speak() {
console.log(this.name + ' barks.')
}
}
let dog = new Dog('Mitzie')
dog.speak(); // Mitzie barks.
上記のコードではAnimalクラスを作成し、extendsキーワードでDogクラスに継承させています。
この方法では extends キーワードを使用してコンストラクタを自動的に設定し、親クラスのコンストラクタを自動的に呼び出します。クラスを使ってコーディングする場合は、関数でクラスをモデリングするのではなく、クラスでクラスを宣言するようにしましょう。
JavaScriptによる綿密な新しいシミュレーションの実装