2008年5月アーカイブ

タイトル

タイトルはホッテントリメーカーに考えてもらったんだけど、ものすごい普通のタイトルが出来上がってびっくりした。まあ普通でいい。

そしてホッテントリにはならないし、ならなくていい。

読書会

今回身に付いたのは9章、クラスの部分。

その前に、まずは prototype チェーンについて guccyon さんのブログでおさらい。
__proto__とprototypeについて - guccyonikki

僕にわかる範囲でまとめると、オブジェクトのプロパティが参照されると、

  1. まず自分のプロパティを探す
  2. 次に自分の prototype から探す
  3. 次からは __proto__ を辿って、継承している prototype から探す

オッケー。ここで僕は考えた。
それなら、最初に読まれる自分のプロパティで完結する場合が一番早いんじゃないか。

ここでの事の本質は早さじゃないとは思うけど、それでもそう考えた。あまりにも短絡的すぎるけど、考えたったら考えた。

でも実際にはむしろ自分のプロパティを参照する方がパフォーマンスが悪くなる場合もあるようだ。

なんでかなー。

function Rectangle(w, h) {
   this.w = w;
   this.h = h;
   this.area = function(){return this.w * this.h;}
}
  • (上記のような記述だと、)生成されたすべてのオブジェクトが3つのプロパティを持ってしまう(p.153)
  • プロトタイプオブジェクトを使用すると、たくさんのオブジェクトがプロパティを継承し共有できる(p.154)
  • あるクラスに10個のオブジェクトがあるとすれば、それぞれのオブジェクトごとにインスタンスプロパティが1個ずつ存在し、全部で10個(p.159)

ってことだからだだね。

試しに以下のクラスを準備して、ベンチマーク取ってみた。

Test1: 自分のプロパティ(インスタンスプロパティ)にメソッドを入れたもの。
function Test1 (){
    this.hoge = 1;
    this.fuga = 2;
    this.count10000	= function(){var i=0;while(i<	10000	){i++;}return i;}
}

Test2: 自分のプロパティにメソッド101個を入れたもの。
function Test1 (){
    this.hoge = 1;
    this.fuga = 2;
    this.count10000	= function(){var i=0;while(i<	10000	){i++;}return i;}
    …
    this.count10100	= function(){var i=0;while(i<	10100	){i++;}return i;}
}

Test3: prototypeプロパティにメソッドを入れたもの。(インスタンスメソッド)
function Test3 (){
    this.hoge = 1;
    this.fuga = 2;
}

Test3.prototype.count10000	= function(){var i=0;while(i<	10000	){i++;}return i;}

Test4: prototypeプロパティにメソッド101個を入れたもの。
function Test4 (){
    this.hoge = 1;
    this.fuga = 2;
}

Test4.prototype.count10000	= function(){var i=0;while(i<	10000	){i++;}return i;}
…
Test4.prototype.count10100	= function(){var i=0;while(i<	10100	){i++;}return i;}

Test5: クラスメソッドを101個持つもの(おまけ)。
function Test5 (){
    this.hoge = 1;
    this.fuga = 2;
}

Test5.count10000	= function(){var i=0;while(i<	10000	){i++;}return i;}
…
Test5.count10100	= function(){var i=0;while(i<	10100	){i++;}return i;}

それぞれのクラスを100個ずつインスタンス化し、count10000メソッドを実行させた。
(ただし、Test5 はインスタンス化しただけ)
実行結果

preparing ...
let's go!
.
*** Test1 ***
result : 538.986725[ms]
.
*** Test2 ***
result : 822.986725[ms]
.
*** Test3 ***
result : 536.986725[ms]
.
*** Test4 ***
result : 535.986725[ms]
.
*** Test5 ***
result : 537.986725[ms]
.
finish!

Test2 以外はそれほど変わらない。
Test2 はインスタンス化の時に101個メソッドを持つインスタンスプロパティがコピーされるので、遅い。 だからまあ、プロパティの参照時の早さどうこうじゃないけど。作法として間違ってる。

僕は java を知らない子供たちなので、インスタンスメソッドとかクラスメソッドとか言われてもよくわかんなかったけど、this とか必要ないメソッドはクラスメソッドにしたらいいんだと思う。

ようやく javascript のクラスがわかってきたかなー。



JSON Editor を紹介

今回、幸いにも LT の時間をいただけたので、拙作(一人で作ったわけじゃないけど)の JSON Editorを紹介して来た。

LT はぐずぐずだったけど、JSON Editor自体は結構好評でよかった。

ujihisa さんが発表10分後にブログで紹介してくれたり
rubyneko - ブラウザ上で動作するJSON Editorがすばらしい
kanasan さんが30分以内にいきなり拡張スクリプトを書いてくれたり、正直ちょっとチビりそうだった。

懇親会

初めて懇親会に参加したので、渾身の力を振り絞って懇親会に来た全員に「こんにちは」って言って来た。

懇親会に来た全員の顔と名前も覚えた。覚えてどうすんだっていう話だけど、「あの人がんばってんなー、チクショウ!」なんて思いながら僕もがんばろうと思う。

がんばるっていうか、まあ日々楽しくやっていきたい。

というわけで、主催の kanasan さん, ujihisa さん、運営に携わってるみなさん、ありがとうございました。
みなさんお疲れさまでした。

JSON Editor に uri 指定での JSON/XML 読み込みを機能つけました。

まだ UI は準備できてないですが、以下のような url でアクセスすることで利用可能です。
http://jsoneditor.net/#uri/{JSONのURL}

(例)twitter のパブリックタイムラインの JSON 読み込み
http://jsoneditor.net/#uri/http://twitter.com/statuses/public_timeline.json

(例)このブログの ATOM フィード 読み込み
http://jsoneditor.net/#uri/http://pm.11op.net/atom.xml


昨日は帰ってくるなり寝てしまったので、日曜の真っ昼間に公開です。。

これは 2008/2/24 の Kanasan.JS JavaScript第5版読書会#3 のレポです。
なんと参加から3ヶ月経過してます。
ごめんなさいごめんなさい。

Kanasan.JS JavaScript第5版読書会#4 & 懇親会
に参加したいので、今更ですがレポートアップします。


--------------------------------------
机が見たことない配置になっててちょっとおもしろかった。
目の錯覚で長く見えたり短く見えたりする矢印みたいなやつの、
長く見える方みたいになってた。


p.115 Array の削除用のメソッドは特にない。splice を使う。

p.116 Array の length プロパティは変更可能
length を変更すると、Array の要素も変更される。


var hoge = [1, 2, 3]
hoge.length = 4; // hoge = [1, 2, 3, undefined]

これが Array オブジェクトのみの特徴。
Array 的なオブジェクトを作ることもできるが、その場合は上記特性は持たない。


Array.cocat は非破壊。

Array はオブジェクトなので、比較する時には toString 等の処理が必要。
これ、javascript 書き始めの頃はは理解できなかったなあ。

    [1,2,3] == [1,2,3] // false


arguments は Arguments オブジェクトであって配列ではない。
いわゆる、配列的なオブジェクト。



function h() {
var i = 1;
if(i==1) {
function a() {alert("sss");}
a();
}
}
h();

は実装依存なので、関数リテラルにすべき。

    function h() {
    var i = 1;
    if(i==1) {
	var a = function() {alert("sss");}
	a();
    }
}

arguments.callee.caller も実装依存!

0||function(){console.log(1)}() にすれば式になる
(function(){})() はめんどくさいと思ってたので助かる
+function(){}() でも可?

p.137 arguments.callee とする方が安全
その方が確実に再帰できるし、見た目的にも再帰であることが自明なので。
関数名変更したりもするので。

p.138
関数 property は関数内からのみ参照できる。これ知らなかった。便利。

apply と Math
apply はそういう使い方もできる。


p.140 callee 化
function(a, b ) -> function(a){return function(b){}}
p.144 clousure の例
p.148 Function() コンストラクタは静的スコープを使わない

eval はそのときのスコープを使う

closure の定義についてちょっと意見が別れた感じ。

ということで、初参加の読書会でしたが、こちらもとても勉強になりました。
なかなか復習の時間取れなくてレポート遅延し過ぎました。
主催者及びスタッフの ujihisa さん、Kanasan さん、37to さん、
参加されたみなさん、おつかれさまでした。


それにしても、僕は勉強会に出ると消耗しすぎる。
この日は家に着いてから震えが止まらなくなり、夜半に熱が出た。知恵熱(笑)
高熱にうなされながら見た夢は、やはり javascript のデバッグをしてる夢だった。


Gmailはショートカットキーが便利です。
何が便利って、複数キーの組み合わせによるショートカットがいいんです。

例えば、 Gmail 上で「?」キーを押すと表示されるショートカットヘルプから一部引用すると、

	Jumping
g then i :	Go to Inbox
g then s :	Go to Starred conversations
g then t :	Go to Sent messages
g then d :	Go to Drafts
g then a :	Go to All mail
g then c :	Go to Contacts

        Threadlist selection
* then a :	Select all conversations
* then n :	Deselect all conversations
* then r :	Select read conversations
* then u :	Select unread conversations
* then s :	Select starred conversations
* then t :	Select unstarred conversations
こんな感じ。
"g" の次に "i" とか、"*" の次に "a" とか、グループ化してるわけです。だから、覚えやすい。
僕は "y" くらいしか覚えてないけど。

これがすごく便利なのでどうやってるのか知りたかったんだけど、
Gmail のソースコードは難読化してあって僕みたいなものには読むことができませんでした。

でも、僕たちには hotkey.js というすばらしいライブラリがあります。
LDRFastladderにも使われてるやつですね。
これを拡張して Gmail みたいに複数キーの組み合わせのショートカットを簡単に実現できるようにしました。

使い方

動作デモ を見てください。jqueryが必要です。

ダウンロード

hotkey.multi.js

  • jquery が必須です。
  • 本家は prototype.js 用なので、 jquery で動作するように少し変更している部分があります。
  • 下記の差分を追加するなり、hotkey.js の後にベルファイルで読み込むなりすれば本家のものでも動作するんじゃないかと思います。
  • これつかって JSON Editor のショートカットをちゃんと vi ライクにするよー。

    hotkey.js に追加したコード

    HotKey.prototype._keyfunc = {};
    HotKey.prototype._keylog = [];
    HotKey.prototype._interval = 500;
    HotKey.prototype._timerid = '';
    HotKey.prototype._separater = '+';
    
    HotKey.prototype.invoke = function(input){
    	input = input || this.lastInput;
    	var e = this.event;
    
    	if (input != 'shift') this._keylog.push(input);
    	
    	clearTimeout(this._timerid);
    	var keys = this._keylog.join(this._separater);
    	if(this._keyfunc.hasOwnProperty(keys)){
    	    this._keyfunc[keys].call(this,e);
    	    this.abort && /*Event.stop(e);*/ e.preventDefault ? e.preventDefault() : e.stopPropagation();
    
    	    this._keylog = [];
    	    return true;
    	} else {
    	    var self = this;
    	    this._timerid = setTimeout(function(){self._keylog=[];}, this._interval);
    	    
    	    this.abort && /*Event.stop(e);*/ e.preventDefault ? e.preventDefault() : e.stopPropagation();
    	    return true;
    	}
    }
    

javascript だけで作った pop な JSON Editor できました。

まずはプロモムービーを見てみてください。(1分30秒)


1分30秒でわかる JSON Editor by katamari
(s/as/a/g)

機能はいろいろとありますが、特にこだわったのは、 ショートカットを使って、キーボードから手を離すことなく全ての操作ができるという点です。

JSON や XML を扱うことがある方はぜひ一度使ってみてください。

開発ブログもありますよ。

先取り五月病が治まったのでブログを再開することにした。
3ヶ月空けるとかサボり過ぎだ。


ブログさぼってた内に書きたいことが溜まってるかというと、
これがそうでもない。


それでも、いくつかは書いておきたいこと、書いておかなければならないことがある。


まあそれは追々書いていくとして、
今日帰宅の電車の中で、両サイドから居眠りの女性にもたれ掛かられた。

Twitter にも書いたけど、こんなこと滅多にあるもんじゃない。
記憶が薄れない内にブログにも書いておいた。