JavaScriptはじめの一歩
JavaScriptを勉強したいと思ったのは、静的なHTMLの表現をどれくらい豊かに出来るのか興味があるから。個人的な勉強メモなどをテキストで書いて、閲覧するときはそれをHTMLに変換して読んでいるのだけど、ちょっと使いにくいと感じる面があって、それをもう少し動的なコンテンツに出来ないのかなと。JavaScriptを使ってソースコードの表示非表示や、検索(Pythonのドキュメントに付属する検索みたいなの)を付けるのがさしあたりの目標。
JavaScript言語が採用するプロトタイプベースのオブジェクト指向にも興味があります。Javaなどのクラスベースの言語に比べて、プロトタイプベースのオブジェクト指向言語ではプログラムの書き方がどんな風に変わるのかな。
CodecademyというサイトでJavaScriptの勉強をしています。それから、『パーフェクトJavaScript』を読んでいます。3章まで読みました。
はじめに処理系をインストール。コマンドラインから実行できるRhinoをインストール。さっそくフィボナッチ数列のプログラムを書きました。
function fib(n) { if (n == 0 || n == 1) return 1; else return fib(n-1) + fib(n-2); } print(fib(30))
実行結果です。
1346269
Rhinoでは、-optを付けると最適化が効いて速くなる。-optに指定する数字は-1から9まで。
文字列リテラルには、ダブルクオートとシングルクオートの両方が使える。
js> "Hello World" Hello World js> 'Hello World' Hello World js> "Hello 'foo' World" // エスケープする必要なし Hello 'foo' World js> 'Hello "foo" World' // エスケープする必要なし Hello "foo" World
typeof演算子で値の型が分かる。
js> typeof 1 number js> typeof 1.2 number js> typeof [] object js> typeof {} object js> typeof "foo" string js> typeof object undefined js> object js: uncaught JavaScript runtime exception: ReferenceError: "object" is not defined. js> typeof(typeof(1)) string
typeofの引数に未定義の変数を書くと、undefinedになるのか。typeofの戻り値はstringらしい。
文字列の練習。
js> var s = "あいうえお"; js> for (var i = 0; i < s.length; i++) print(s[i]) あ い う え お js> s[-1] js> s[0] あ js> s[1000]
範囲外アクセスしてもエラーにならない。
Stringについて。
js> String function String() { [native code for String.String, arity=1] } js> typeof String function js> String("foo") foo
Stringはfunction。「function String() { ... }」と表示されることから、関数の引数表示は省略されるのだろうか?関数を定義して確かめる。
js> function add(a, b) { return a + b; } js> add function add(a, b) { return a + b; }
自分で定義した関数については、引数表示もきちんと行われている。コメントも追加してみる。
js> function sub(a, b) { > // subtract > return a-b; > } js> sub function sub(a, b) { return a - b; }
コメントは取り除かれる。
『パーフェクトJavaScript』では行末にセミコロンがあるのに気がついた。セミコロンは省略可能みたいだけど、セミコロンを付けるようにしたほうがいいのかな。
比較演算子==, ===の練習
js> "foo" == new String("foo") true js> "foo" === new String("foo") false js> "foo" == "foo" true js> new String("foo") === new String("foo") false js> var s = new String("foo") js> s === s true js> new String("foo") == new String("foo") false
うーむ。new String("foo")同士の==による比較はfalseになるのか……。typeofで型を確認する。
js> typeof "foo"; string js> typeof (new String("foo")); object
「new String("foo")」の型は、stringではなくてobjectだった。Stringの型はfunctionだったよね。
js> typeof String; function
substring()の呼び出し
js> "foo".substring(1) oo js> "foo".substring(2) o js> "foo".substring(3) js> "foo".substring(4) js> "foo".substring function substring() { [native code for String.substring, arity=2] } js> typeof ("foo".substring) function js> var f = "foo".substring js> f function substring() { [native code for String.substring, arity=2] } js> f(1) object global]
最後の実行結果がわからない。fは文字列として"[object global]"を保持しているみたい。でも、何故? f(1)の実行結果には"oo"を期待していた。
「typeof (new String("foo"))」でobjectが返される。このオブジェクトをstringに変換出来ないだろうか?toString()を使うとstringに変換出来る。
js> var s = new String("foo"); js> typeof s; object js> typeof s.toString(); string js> var t = s.toString(); js> t foo js> s.toString() == s.toString(); true js> s.toString() === s.toString(); true
newを付けずに、String()でもstringに変換することができる。
js> var s = new String("foo"); js> typeof s; object js> var t = String("foo"); js> t foo js> typeof t; string
なんだか、newの使いどころがいまいちよく分からない。newの詳しい使い方はこの先のお楽しみ。
toString()で基数変換が出来る。
js> 255.toString(16); js: "<stdin>", line 143: missing ; before statement js: 255.toString(16); js: ............^ js> (255).toString(16); ff js> (255).toString(2); 11111111 js> (255).toString(1); js: illegal radix 1.