第 5 版 JavaScript[1]
http://d.hatena.ne.jp/janus_wel/20081104/1225758511 の続き。ダメだこの本ツッコミどころが多すぎる。もう少し軽く読めと言うことなのかな−。とりあえず 4 章 変数まで。あとこの本やっぱり著者の David 氏がぶっ飛んでる感じ。以下は 4 章 変数の p.50 から引っ張ってきた文章ね。いろいろ沸き起こってくるものはあるんだけどシンプルにこれあんたがデザインした言語じゃないだろって点のみを主張する。
JavaScript はデータ型の指定が不要なので、ほかのプラグラミング言語より簡潔なコードになります。 C++ や Java のようにデータ型の指定が必要な言語は、厳格な記述が強制されるので、長くて複雑なプログラムを作成しても、保守や再利用が容易であるという利点があります。一方、 JavaScript のスクリプトはそれほど長くないことが多いので、厳格さが強くは要求されません。このため、構文が簡潔になるという利点が優先されています。
以下細かいところへのつっこみ。
- warnings
- block scope
- ないって書いてあるけど 1.7 から導入された let で実現された ( https://developer.mozilla.org/ja/New_in_JavaScript_1.7#let_.e3.82.92.e4.bd.bf.e3.81.a3.e3.81.9f.e3.83.96.e3.83.ad.e3.83.83.e3.82.af.e3.82.b9.e3.82.b3.e3.83.bc.e3.83.97 ) ので使える場合はこっち使った方がいいと思う。まぁ好みだとは思うけど、 var が関数内スコープっていうのは直感に反するしね。
function foo() { alert(i); var i = 0; } foo();
が「そんな変数はねぇよ !!」って怒られない上に 'undefined' が表示されるのは混乱の元だよね。
- ないって書いてあるけど 1.7 から導入された let で実現された ( https://developer.mozilla.org/ja/New_in_JavaScript_1.7#let_.e3.82.92.e4.bd.bf.e3.81.a3.e3.81.9f.e3.83.96.e3.83.ad.e3.83.83.e3.82.af.e3.82.b9.e3.82.b3.e3.83.bc.e3.83.97 ) ので使える場合はこっち使った方がいいと思う。まぁ好みだとは思うけど、 var が関数内スコープっていうのは直感に反するしね。
- garbage collection と参照カウント
- 参照されることがなくなると破棄されるらしい。これは Perl と同じだと解釈すればいいのかな。とすると自己参照してる変数はいつまでも残るということだね。あと closure ( http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3 ) が簡単に作れるということでもあるな。 JavaScript で closure といえば有名なのは prototype.js 出身の Function#bind だね。と、ここまで書いて Perl は未だに参照カウント方式使ってんのかな−、全然話題にならないからたぶんそのままなんだろうなーとか、 prototype.js って最近話題にのぼってこないな−、そういえば名実ともに de facto standard になった jQuery はいじってみないとなーとかカカッと思った。
- global object, function local object, scope chain
- 超重要。変数名の解決をどのようにしているかというハナシ。たとえば C/C++ は変数自体がメモリ上の特定の場所のエイリアスなので高速だけど危険、C++ のメンバ変数・関数も普通直接的に表しているので解決にかかる時間は少ないけど virtual 指定するとサブクラスで挙動を変更することができるという利点が得られるものの vtbl による解決が間に入るので遅くなる、 Perl はもともと変数名を symbol table に保持するという方法をとっているのでいろいろ無茶ができるんだけど遅い、と。
- で、 JavaScript では object ありきで変数名も標準関数も何らかの object の property である、と。 symbol table や型グロブという概念がある Perl よりわかりやすいし何よりキレイだ。 global object である ( と書いてある ) Window や function local object である ( と書いてある ) Call はどうすれば見えるのかな。
:echo Window
や:echo let foo = function () {}; [a for (a in foo)]
では中身が見えない。 Window に関してはエラーが出ないから存在してるってことはわかるんだけど。まぁ見えなくてもいいものだし見えないようにしてるのかもしれないなぁ。 - scope chain も見える範囲の object 内の property を順次なめていくというだけのことで見に行く順番の制御によって変数の局所性を実現している。これは美しい考え方だと思うな−。あんまり美しいとか使いたくないんだけどここは素直にそう思ったわ。 with は scope chain を一時的に制御できるということがわかればいろんなことがわかってくるはず。…あーでもよく考えると scope chain て symbol table や vtbl みたいなもんか。そうすると元からあったアイディアをうまいこと構造化したというだけのハナシなのかな。
- 内部表現とビット演算
- 基本型の変数は固定長だって書いてあるんだけどいくつだろうと思っていろいろやってみた。結果は整数の内部表現 ( http://ja.wikipedia.org/wiki/2%E3%81%AE%E8%A3%9C%E6%95%B0 ) は signed int ( 32bit ) でその範囲 ( -2147483648 〜 2147483647 ) を越えるものや小数は double ( http://ja.wikipedia.org/wiki/%E5%80%8D%E7%B2%BE%E5%BA%A6 ) ということみたい。
- ビット演算は 32bit に変換されてから実行されるらしいんだけど内部表現が signed なので最初ちょっととまどった。
~0
が -1 なのはやっぱり混乱すると思うなぁ。あとビット演算なんかつかわねぇだろって書いてるけど使うと思うぞ。パッと思いつくのは RGB 関係だけど css いじるときにも有用な場面ありそう。 - まぁここらへん意識しないための言語だし意識せざるを得ない状況ってかなり特殊だと思うんだけど知ってるか知ってないかで変わるしねー。
// result: -2147483648 :echo 1 << 31 // result: 1.7976931348623157e+308 :echo Number.MAX_VALUE; // result: 5e-324 :echo Number.MIN_VALUE; // result: -2 // 倍精度浮動小数点数での表現の下位 32bit ( 仮数部の一部 ) // 11111111 11111111 11111111 11111111 -> 11111111 11111111 11111111 11111110 :echo 4294967295 << 1 // result: 0 // 0 00000000 00000000 00000000 00000000 -> 00000000 00000000 00000000 00000000 :echo 4294967296 << 1 // result: 2 // 0 00000000 00000000 00000000 00000001 -> 00000000 00000000 00000000 00000010 :echo 4294967297 << 1