tohokuaikiのチラシの裏

技術的ネタとか。

jQueryでClassみたいな感じ

こっちのスライドからしばらく拝借

http://www.slideshare.net/SlexAxton/how-to-manage-large-jquery-apps


--------- 引用開始 -----------

このスライドを作った理由は、もうこういうjQueryでサイト作って後でぐちゃぐちゃになるっていうのを繰り返すのはうんざりだから。

そして、メンテナンスするのも大変ですよね。

こんなのだったら良くないですか?

変更したDOMがアプリケーションを壊すことは無い
コードの一部分を再利用できる
ファイルはタスクごとに分割されているけど、ページの上の部分で何百もロードをする必要がない
コードを見たときに何をしているかが把握できる

独断と偏見により次の4つのことに注視してみる
  1. インターフェイス
  2. Mixin
  3. DOMからObjectへの相互変換
  4. 依存性管理
JavaScriptネイティブなうそんこクラス

こんな感じ。

  1. まぁふつうに気持ち悪いよね
  2. JavaScriptはClassっぽい書き方もできる関数型の言語
  3. 一度使ったら使いたくなくなると思う
Classっぽい書き方

こんなの

  1. プログラマならよく知っていると思う
  2. NativeじゃないからちょっとOverheadはあるよね。
  3. 真のJavaScriptiestはやらないだろうけど、まぁ誰がきにするかっていう感じで。
  4. いろいろな実装がある*1
Prototype的なインターフェイス

こんな感じにObject.createを定義して

こんな感じでCloneします。

  1. JavaScript言語的にピッタリな感じ
  2. jQuery.extendは簡単な多重継承
  3. そんなに複雑ではない。
MixinのようなOptionの使い方

さっきのPrototype的なClassの作り方に、$.extendを掛け合わせてmixin的にOptionの設定を行うことができる。*2

こんな感じ

--------- 引用終了 -----------

で、なんだったかというと・・・

長々とやってしまったけど、これ読んで、jQueryでClassを使いたい・・・というか、パッケージ管理的にやりたいって時、こんな関数を1個作ればってのが興味深かった。

Object.create = function(o){
    var F = function(){};
    F.prototype = o;
    var f = new F();
    return f;
};
// Classを定義する
var ClassA = {
  options:{
      color: "#BADA55",
      height: 160,
      wieght: 320
  },
  init: function(param){
      console.log("color >> ", this.options.color);
  }
};
// インスタンスを生成
var InstanceA = Object.create(ClassA);
InstanceA.init("param"); // コンストラクタ 

でも、これだと作ってすぐコンストラクタが働かないから

Object.create = function(o){
    var F = function(){};
    F.prototype = o;
    var f = new F();
    f.init(arguments.length>1 ? arguments[1] : undefined);
    return f;
};

こんな感じかなぁ。

クラスの継承はこんな感じ。

var ClassB = $.extend(ClassA, {
  param1: "foo",
  func1 : function(str){
      alert(str);
  }
});

だけんど、普通にoverrideされた場合親クラスのメソッドを呼べないよね。まぁ、いままでJavaScriptでそんなの呼んだことそうそうないんだけど。

Classによってはinit時にOptionsを指定して、もともとのOptionをそれで上書きしてインスタンス作成したいとか。要はスライドにあった例なのですが。

そんな場合は、

var ClassA = {
  options:{
      color: "#BADA55",
      height: 160,
      wieght: 320
  },
  init: function(options){
      $.extend(this.options, options);
  }
};
var objectA = Object.create(ClassA, {color:"#ff0000"});
console.log(objectA.options);  // Object { color="#ff0000", height=160, wieght=320}

こんな感じ。

多分、ちろっと使うならこれで十分な感じがする。他に、ちゃんとClass昨日が使いたかったら
Mootools Classes, LowPro, Base2, とかいろいろあるよっていう。Class使うためだけにPrototype.jsはちょっとなぁ・・・と思ったんです。

*1:There’s a bunch-o-options: Simple Inheritance, Mootools Classes, LowPro, Base2, and MOAR! 多分そんな感じ?

*2:mixinって多重継承の実装の一つって理解であってる?