トップ «前の日記(2011-07-30) 最新 次の日記(2011-08-01)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2011-07-31

_ JavaScriptで定義済みオブジェクトを使いまわす

なんとなく単に遅れているだけのような気もするが、JavaScriptというプログラミング言語の特性を理解せずに使っているとしか考えられない例を見ていろいろ考える。

あるシステムを作っているのだが、そこでJavaScriptで作られたフレームワークが使われていて、そのフレームワークそのものは実に巧妙で良いのだが、利用している側がどうもJavaのウルトラサブセットくらいのつもりで利用しているみたいでぎょっとするようなコードを見て、使い方を提案してみたり。

たとえば、次のようなコードがあって、びっくりする。

function SomCommonObject(_caller) {
  this.caller = _caller;
  FrameworkObject.registerObject(this);
}
SomeCommonObject.prototype.onFoobar = function() {
  if (this.caller.id == 'a') {
    ...
  } else if (this.caller.id == 'b') {
    ...
  } else ...
  } else {
    alert('呼び出し元のIDと処理を登録してください!!');
  }
}
SomeCommonObject.prototype.onBaz = function() {
  ...

onFoobarという関数はフレームワーク関数でハリウッド原則にしたがっているのだが、利用している側が何か大きく勘違いしている。

いや、これでは共通のオブジェクトでハリウッドメソッドを使っている意味がほとんどないではないか。確かにonFoobar以外のonBaz以降のハリウッドメソッドはa~zの誰がnewしようと共通で使えるのだから、このオブジェクトを共通で利用するという設計は正しい。

しかしonFoobarで誰が作ったかによってそれぞれの処理を記述しているのは何が何でも異様だ。共通で使うものを使うもの全員が内部に処理を記述するなんておかしいだろ(ソースコード管理的な意味ですら)。呼び出し側固有の処理は、呼び出し側が呼び出し側に定義すべきじゃん。

だって、継承できないし……とか、いや、それはそういうくだらないことはしなくても良いように巧妙にJavaScriptが設計されているのだから、JavaScriptの言語の機能を利用すれば良い。

JavaScriptのオブジェクトのホットスポットはどう記述すべきだろうか?

FrameworkObject.registerObjectの中の人から呼ばれるかどうかで変わるが、以下のようにするのが良いと思う。

function CallerA() {
  this.common = new SomCommonObject(function () {
    // onFoobarの処理
  });
  ...
}
//----------
function SomeCommonObject(onfoobar) {
  if (onfoobar != null) {
    this.onFoobar = onfoobar;
  }
  FrameworkObject.registerObject(this);
}

もし、そこら中でSomeCommonObjectをnewしまくるのなら、コンストラクタの引数に直接記述せずに以下のようにしても良い。

function CallerA() {
  this.commonOnFoobar = function() {
    ... // インスタンス毎に変えるものがあるならば。無ければprototypeに定義すれば良い。
  }
}
CallerA.prototype.foo = function() {
  var common = new SomeCommonObject(this.commonOnFoobar);
  ...
}

そこで、jQueryのドキュメントで、要素のon属性にスクリプト片を書くのではなく、 $(document).readyの中でDOMの要素オブジェクトに直接記述するという方法を推奨している理由の中には、もしかすると、関数をファーストクラスオブジェクトとして記述するという良い習慣を身に着けさせようという意図もあるのかな、と考えてみたり(多分、実際に「We have a clean separation of structure (HTML) and behavior (JS)」ということだけなんだろうけど)。

以下余談と自戒:自分でJavaScriptという名前についだまされてしまうのは、Java流のばかみたいに長い変数名やら関数名やら属性名やらをつい定義してしまうこと。そのため、おそろしいほどの未定義エラーに見舞われる。動的言語はCの良き慣習にしたがうのが鉄則だな。lenを書き間違えたことは一度たりともないが、lengthをlegnthにしてしまうことは100回書けば2~3回はあるわけだhし(AruwakeDashiというのも、単にAruにすべきだ)。

_ ATOK 2011

今年はパスしようかなぁとか思っていたら、それを察知したらしくJust MyShopがポイントをぽこんと付けてきた。

で、ATOK 2011 for MACを買ったわけだが、Vista以降のIMEにはうんざりしているので(7のはVistaやOffice 2010のやつみたいにはひどくないが、それでもなんかこちらの期待とは異なる動作をすることがある)、変換学習や辞書が同期できるのだから、WindowsにもATOKを入れれば良かったと後から後悔した。

ATOK 2011 for Mac + Windows 通常版

(これのAA版はライセンス的に問題なさそうだが、MAC用に以前のバージョンの時に買った辞書(ロングマンや広辞苑)をWindowsで使うことは可能なのかがいまいちわからないな。あと、ATOK Syncアドバンスの絵にAndroidが出ていないのだが、もしシェアできるのなら、Syncしたい(Androidで日記を書くのは変換がほとんど効かないのでえらく苦痛(それだけじゃなくて、カーソル移動がほとんど異常というのも困った点だが)。携帯のほうが日本語文章書きという点からは全然上だった)。)


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|

ジェズイットを見習え