JavaScriptの<<とMath.powの違い

投稿者 nanki 2010-05-18 22:26:00 GMT

某所で話題になったのでまとめ。

JavaScriptで、

200 << 24
=> -939524096

200 * Math.pow(2, 24)
=>3355443200

の結果が違うという話。

200 が 7~8bitなので、すぐに32bitの壁だとわかるが、これは仕様なのか、実装によるものなのか。

ECMA-262, p.76

  1. Let lref be the result of evaluating ShiftExpression.
  2. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating AdditiveExpression.
  4. Let rval be GetValue(rref).
  5. Let lnum be ToInt32(lval).
  6. Let rnum be ToUint32(rval).
  7. Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.
  8. Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.

つまり、

(signed int32)(ToInt32(200) << (ToUint32(24) & 0x1F))

こういう感じになる。

結果は32bit符号付き整数なので、こうなるのは仕様。

参考:

Objective-J および cappuccino とそのvim補完

投稿者 nanki 2009-02-05 23:03:00 GMT

vim objj

しばらくはprototype.js や jQuery、時々はExt JS で楽しく遊んでいたけども、デスクトップアプリケーションのような物を作るのには力が不足していると感じていた。(機能が、ではなく、抽象化の程度が)

年初めくらいに cappuccinoというプロジェクトを見つけてきて、しばらくソースを眺めていたりしたのだけど、これはいい。 久々にピリピリ来るプロジェクト。

最近、iPhone SDK などでObjective-Cに触れて、Cocoa APIに慣れ親しんだせいもあるけど、それを差し引いても、よくできている。 興味と暇のある人は是非、調べてみて欲しい。

実際に、Keynote にしか見えないアプリケーション なんかもこれで作られている。

ちょっとソースを見ると、こんな調子だ。

<script type="text/javascript">
    OBJJ_MAIN_FILE = "main.j";
</script>
<script src="Frameworks/Objective-J/Objective-J.js" type="text/javascript"></script>

main.j というのが、Objective-J 言語で書かれていて、Objective-J.js を読み込むと、その場でJavaScriptにコンパイルされる。

元々、Objective-C は、Objective-Cのランタイム(Cの関数)とプリプロセッサだけでこしらえてある(と思う)のだが、その手の抜けた?実装とは裏腹に強力なオブジェクト指向機能を持っている。

今回、Objective-J がその手法をJavaScriptに対して適用したのを見て、この方法の持つシンプルさと力ににやにやせずにはいられない。(JavaScriptにOOを導入するとは!)

でも、Cocoa APIはフルスペリングでAPIが長いのでとても覚えられない。 IDEなどのコード補完機能がないと書く気が起こらない…ということで、vim の補完関数を作った。

github に置いてあるので、使うなり改良するなりしてください。

関係ないけど、Objective-J ではメソッドの定義に型を書くんだけど、コンパイルの時点で廃棄されている。(ので間違っててもコンパイルは通る) しかし、コード補完を作るにあたって、この型情報は非常に役に立った。

参考:


iPhone用 JavaScript コンソールにPermalink機能を追加

投稿者 nanki 2008-09-17 00:41:00 GMT

前回作成したコンソールに、permalink機能を追加。

URLの#以降に/jsconsoe/#javascript:alert(123)といった形で保存する。

このままブックマークに保存すれば、書いている途中のスクリプトを次回ロードできる。

ブックマークした後に、#以前を削除すれば、そのままbookmarkletに。


iPhone/iPod touch用 JavaScript コンソール

投稿者 nanki 2008-09-09 18:55:00 GMT

iPhone/iPodのキーボードは、まったくもってプログラミングに向かいないけれども、 ちょっとしたJavaScriptを試してみたい時はあるので、どうにかならないか試してみた。

jsconsole for iphone

JavaScript Console for iPhone

若干妙なところもあるけど、一応動く。 ちょっとしたコードなら、思ったよりさくさく?かける。

高度なカーソル移動や、単語境界まで削除、みたいな機能は欲しいなぁ。

やっぱり、touchイベントを使うので、普通のSafariで動かない。めんどい… textareaのスクロールも…

AJAX Libraries API を使って、著名なライブラリをロードできる機能もつけてみた。

http://tools.netswitch.jp/jsconsole/?lib=j,ju こんな感じにすると、jQuery, jQueryUIを読み込んでいる(はず).

j=jQuery, ju=jQuery UI, p=prototype, s=scriptaculous, m=mootools, d=dojo

書き上がったJavaScriptはメールで送信できるらしい。

参考:

iPhone/iPod用Todoリスト

投稿者 nanki 2008-09-04 05:40:00 GMT

動機: MobileSafariはマウス系のイベントが(そのままでは)あんまり動いてくれないために、哀しい思いをする事が多々あるので、一度その辺をちゃんと調べてみたかった。

結果: いい!楽しいものができた。

せっかく作るのだから、タッチセンサを生かしたインターフェースにしたかったので、 まずは Todoリストに必要な本質的な機能を洗い出す。

  • タスク追加
  • 優先順位
  • 完了
  • 削除

タスクの編集機能なんかははあえて省いているし、タスク名しかない。

それらの機能を連続的なインタラクションの中に組み込むことを主眼に構想を練る。

「削除」→「本当に削除しますか」→「OK」なんてのを5回も繰り返すのはいけない。 でも、間違えて削除してしまうようなのもダメ。

Todo list for iPhone
指先一つで一気にタスクが完了する魔法のツール!

html/css/js で動くモックを作って、最後にモデル部分をサーバ側と通信するように調整して完成。

試していただける方はこちらからどうぞ。

Create Accountすると、専用のURLが作成されます。 URL認証なので、そのままブックマークすればOK. URLをそのまま晒して*ジャック計画とかが漏れても自己責任で。

最後にJavaScript的な話をすると、

  • マウスイベントを全部iPhone用のイベントに置換
  • CPUパワーの違いでイベント処理がいっぱいいっぱいになる対策
  • 絶対位置を指定するデバイスなので、マウス用のインタラクションを一部修正

というような点でscriptaculousのdragdrop.js を直接書換えています。 なので、普通のSafariでも動きません!あしからず。

追記: Safari でも動くようにした。

ご意見・感想などはコメント欄へ。

参考:

todo.switch - todo.dotswitch.net


JavaScript デバッグツール - コードゴルフIE杯

投稿者 nanki 2008-06-12 13:31:00 GMT

先ほどのdebug.jsを読み込むBookmarklet.

debug

javascript:void((function(r){var d=document,w=arguments.callee,v,t=r[0],n=r.slice(1);if(t){v=t.split('$');if(v[1]){try{eval(v[0]);t=v[1]}catch(e){setTimeout(function(){w(r)},100);return}}v=t.split('@');if(v[1]){try{eval(v[0]);w(n);return}catch(e){t=v[1]}}d.body.appendChild(d.createElement('script')).src='http://tools.netswitch.jp/jstools/'+t+'.js';w(n)}})(['Prototype@prototype','Prototype$Effect@effects','Effect$DebugTool@debug']))

外部のJavaScriptを読み込むには、JSONPなどでも使われているscriptタグの動的生成を使うのだが、これが非同期で、prototype.js, effect.js, debug.jsを順番に読み込まないといけない今回のような場合はちょっと工夫が必要になる。

effect.jsはPrototype定数が定義されるまで読まない、debug.jsはEffect定数が定義されるまで読まない、など。

それとは別に、すでにprototype.jsが読み込まれている場合は、prototype.jsの読み込みをご遠慮する機能もつけてある。 ブックマークレット中の最後の方の@とか$とかにはさまれているあたりがそれ。 evalして例外が上がらなければ、あるいは上がれば、ロードして、次へ。

しかし、どういうわけか、一番使いたいIEで動かない。 alertを追加するしないで、syntax errorがでたりでなかったりするあたりで、ようやく、bookmarkletの文字数制限を思い出した。

というわけでそこから先は、コードゴルフIE杯。 今では、400台前半に落ち着いて、無事動くようになり、IE6SP2でも余裕がある。

参考:

Rules for Bookmarklets


JavaScript デバッグツール

投稿者 nanki 2008-06-12 13:04:00 GMT

inspection

いろんなブラウザでチェックしているうちに、ちょくちょく使う機能をまとめてみた。

DebugTool.alertbox(msg)
  console.log の代わり。

DebugTool.report(target, filter)
  target内の関数呼び出しを監視。
  内部でprototype.js とかを使いまくってるので、DebugTool.report(Prototype)とかはやらないこと!

DebugTool.inspect(target)
  DOM ツリーを遡って、タグ名、id、class属性などを表示。

DebugTool.shell()
  シェルっぽいのがでてくる。未完成、おまけ。

などなど。

要 prototype.js, effect.js

debug.js

これを任意のページでロードするbookmarkletの話は、別エントリで書く。

reportの中身は結構面白いと思う。

  report: function(target, filter) {
    var func = function(name) {
      return (function(a){
        var result = a.apply((function() {return this}).apply(a), $A(arguments).slice(1));
        DebugTool.alertbox(name + '(' + $A(arguments).slice(1).inspect().gsub(/^\[|\]$/, '') + ') -> '+$A([result]).inspect()+'.');
        return result;
      });
    };

    for (key in target) {
      if (typeof target[key] == 'function' && (!filter || filter(key))) {
        target[key] = target[key].wrap(func(key));
      }
    }
  },

wait もおすすめ。

  wait: function(wait_for, callback) {
    var check = false;
    try{
      check = (typeof(wait_for) == 'function') ? wait_for() : eval(wait_for);
    }catch(e){
    }

    if(check){
      callback(check);
    } else {
      var wait = arguments.callee;
      setTimeout(function(){wait(wait_for, callback)}, 100);
    }
  },

JavaScriptでウィンドウがピタッ!

投稿者 nanki 2008-05-13 03:23:00 GMT

世間では window.moveByの時代がくるとか言われているそうですね。

こちらは、window.moveToだけど…

demo

参考:

window.moveBy の時代がくる、こない - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtech


RubyでもJavaScriptでも動くコード

投稿者 nanki 2008-04-30 14:19:00 GMT
"#{"/*"}"
  Ruby Code.
__END__
*/
  JavaScipt Code.
"#{"/*"}"
  Ruby Code.
__END__
*/
  JavaScipt Code.

他にもあると思うけど。

こういうのどうやって探したらいいんだろう。

追記:

たった二つから使っていいのかわからないが、polyglotと呼ぶらしい。