クラスっぽく書く
JavaScriptのクラスはECMAScript6から。
それ以前のJavaScriptでは、new演算子の挙動「オブジェクトのインスタンスを返却」と、thisの挙動「関数内で呼び出すthisは関数呼び出し元のオブジェクトを参照するが、new演算子を使ってインスタンス化した場合は、thisはそのインスタンス自身を指す」を利用してクラスっぽく書くことが出来るので、それで代用する。
//クラス定義
var MemberClass = function(name, age, birthplace){
this.name = name;
this.age = age;
this.birthplace = birthplace;
this.Appeal = function(){
return '私の名前は' + this.name + 'です。年齢は' + this.age + '歳。出身地は' + this.birthplace + 'です。';
}
}
var tanaka = new MemberClass('田中', 18, '東京');
ここでは例としてメソッドもクラス定義の中に記述したが、メソッドはprototypeプロパティで管理するのが望ましい。
オブジェクトは動的に変更できる
オブジェクトに後からメソッドやプロパティを追加できる。
MemberClass.AgeCall = function(){
return '私の年齢は' + this.age + '歳です。";
}
オブジェクトに後からメソッドやプロパティの削除もできる
delete MemberClass.AgeCall;
プロトタイプ prototypeプロパティ
オブジェクトにはメンバを追加するためのprototypeプロパティが用意されている。
メソッドは、メモリ使用量削減のためprototypeを使って登録する。
クラスの場合、プロパティ(変数)は生成したインスタンスごとに異なるので問題ないが、メソッドはどのインスタンスでも共通。それなのにクラス内にメソッドを定義していると、インスタンス毎にメソッド分のメモリも消費してしまう。
外側で関数定義し、prototypeに追加することで、各インスタンス共通でメソッドへの参照を持つ形になりメモリが無駄にならない。
//クラス定義
var MemberClass = function(name, age, birthplace){
this.name = name;
this.age = age;
this.birthplace = birthplace;
}
MemberClass.prototype.Appeal = function(){
return '私の名前は' + this.name + 'です。年齢は' + this.age + '歳。出身地は' + this.birthplace + 'です。';
}
var tanaka = new MemberClass('田中', 18, '東京');
console.log(tanaka.Appeal()); //tanaka.prototype.Appeal()とは書かない。
prototypeへの追加はこのような書き方もある。
MemberClass.prototype = {
Appeal:function(){ return '私の名前は' + this.name + 'です。年齢は' + this.age + '歳。出身地は' + this.birthplace + 'です。'; },
AddNum:function(a,b){ return a + b; }
}
プロトタイプを使って継承
//継承元クラス定義(スーパークラス)
var HumanClass = function(){};
HumanClass.prototype = {
printName : function(){ console.log('私の名前は' + this.name); }
};
//継承先クラス定義(サブクラス)
var MemberClass = function(name, age, birthplace){
this.name = name;
this.age = age;
this.birthplace = birthplace;
}
MemberClass.prototype = new HumanClass(); //ここでprototypeをスーパークラスObjectにすることで継承
MemberClass.prototype.Appeal = function(){
return '私の名前は' + this.name + 'です。年齢は' + this.age + '歳。出身地は' + this.birthplace + 'です。';
}
//サブクラスを使ってインスタンスを作成
var tanaka = new MemberClass('田中', 18, '東京');
console.log(tanaka.printName()); //出力:私の名前は田中
console.log(tanaka.Appeal());
変数を同名のプロパティとして設定(ES6)
オブジェクト作成時に、変数を渡せば、そのまま変数名をプロパティ名として作成してくれる。
let name = 'マイケル';
let age = 20;
let actor = {name, age};
console.log(actor.name); //マイケル
console.log(actor.age); //20
旧来の書き方なら、こう。
let name = 'マイケル';
let age = 20;
let actor = {
name: name,
age: age
};
メソッドの定義(ES6)
旧来の書き方
let obj = {
x:10,
y:20,
add_num:function(a, b){ return a + b; }
};
ES6では関数の場合、キー名が不要になった。
let obj = {
x:10,
y:20,
add_num(a, b){ return a + b; }
};
プロパティ名を動的に生成(ES6)
[]で囲むことで、式の値から動的にプロパティ名を生成できる。let i = 0;
let obj = {
['param_' + i++]: 10,
['param_' + i++]: 20,
['param_' + i++]: 30
};
console.log(obj.param_0); //10
console.log(obj.param_1); //20
console.log(obj.param_2); //30