“Class” – Alphabetical Advent Calendar 2013
この記事は賞味期限切れです。(更新から1年が経過しています)
“C” は Class の “C”。
レガシーなJavaScriptのクラス
JavaScriptでクラスと言っても、現行のバージョンではclass構文が実装されていない為、 クラスを使いたい場合はレガシーな方法をとるか、フレームワークの機能やクラスライブラリを使ってクラスを定義する事になります。
今回は生のJavaScriptでレガシーなクラス(のようなもの)を書いてみる事とします。
プロトタイプを利用するタイプ
// コンストラクタ
var Person = function(name, age){
this.name = name;
this.age = age;
};
// 属性の定義
(function(my){
my.name = null;
my.age = null;
my.hello = function(){
return "こんにちは、{{name}}です。{{age}}歳です。"
.replace("{{name}}", this.name)
.replace("{{age}}", this.age);
};
}(Person.prototype));
var john = new Person("ジョン・カビラ", 54);
john.hello(); // "こんにちは、ジョン・カビラです。54歳です。"
function の prototype に属性を生やしていき、new でインスタンスを生成します。 生成されたオブジェクトは、 prototype の中身を全て継承します。 人によって書き方や趣向がかなり異なる印象です。 jQuery等を読み込んであるならば、extendを利用しても見易くて良いかもしれません。
$.extend(true, Person.prototype, {
name: null,
age: null,
hello: function(){ ... }
});
同じく $.extend で他のクラスの継承も出来ますね。
$.extend(Person.prototype, Animal.prototype);
コンストラクタ内だけで完結するタイプ
関数型などと呼ばれているのを聞いた事があります。 前項の物と大きく異るのが、プロトタイプからの継承ができない点でしょうか。
var Person = function(name, age){
this.name = name;
this.age = age;
this.hello = function(){
return "こんにちは、{{name}}です。{{age}}歳です。"
.replace("{{name}}", this.name)
.replace("{{age}}", this.age);
};
};
非常に狭いスポットで使用したい場合などはお手軽で良いのかもしれませんが、 prototype を継承して新しいインスタンスを生成するのが new 演算子の本分だと思うので、 基本的にはそれに則った形をとったほうが良いかな、と考えています。
レガシーではない選択肢
昨今では新しい実装やリソースも沢山増えてきたので、選択肢が幅広くあります。
altJSを使う
ここ数年で一気に盛り上がってきた altJS はおそらくどれもクラスが実装されているはずなので、それを利用する選択肢。 ポピュラーなのは CoffeeScript、TypeScript、Haxe、JSX 等。 ネックは、いずれも大なり小なりJavaScriptから離れた構文になる為、学習コストがかかる点です。
例えば、Haxeでクラスを定義するとこんな具合になる様です。 ActionScript3(EcmaScript4)にかなり近い構文になっているので親しみを感じる人もいるかもしれませんね。
class Person {
public var name:String;
public var age:Int;
public function new(name, age){
this.name = name;
this.age = age;
}
public function hello(){ ... }
}
フレームワークを使う
最近一番耳にするのは Backbone.js です。
Backbone には Model や View などの基底クラスが実装されていて、 それを継承して独自のクラスを定義していきます。 例えば Model であれば、ゲッターセッターや Ajax まわりの機能が既に盛り込まれているので、 それらを覚えさえすれば非常に効率的にアプリケーションを制作できるでしょう。
var Person = Backbone.Model.extend({
defaults: {
name: null,
age: null
},
initialize: function(name, age){
this.set({ name: name, age: age });
},
hello: function(){ ... }
});
var person = new Person("John", 54);
コメント