配列

生成

Array コンストラクタを利用する方法。引数に配列のサイズを指定できるけど,必要なら勝手に大きくなってくれる。

var a1 = new Array();
a1[0] = "dog";
a1[1] = "cat";
a1[2] = "elephant";

コンストラクタに値を直接渡す方法。

var a2 = new Array("dog", "cat", "elephant");

リテラル。

var a3 = ["dog", "cat", "elephant"];

要素の型は何でも良い。

var a4 = ["Andy", 16, new Date()];

配列の長さ

長さを得るには length プロパティ。必要なら自動的に長くなる。

var a = new Array("andy", "bill", "charlie");
document.write(a.length, "<br>");      // => 3

a[4] = "eddy";
document.write(a.length, "<br>");      // => 5

document.write(a[3], "<br>");      // => undefined

↑a[3] は代入されてないので,undefind になる。

sort

sort() メソッドに引数には,比較関数を渡す。単純に大小関係で比較するなら省略していい。

var a = [4,2,1,5,6,3];
a.sort();
for (i=0; i<a.length; i++) {
    document.write(a[i], ",");      // => 1,2,3,4,5,6,
}

比較関数は,2引数 a,b をとって 正の値/0/負の値 のいずれかを返すように作る。

a > b正の値
a == b0
a < b負の値

連想配列

Array の添字に整数(インデックス)じゃなくて文字列(キー)を使うと連想配列になる。

var pets = new Array();

pets["Andy"] = "dog";
pets["Bill"] = "cat";
pets["Charlie"] = "elephant";

for (name i pets) {
    document.write(name, ": ", pets[name], "<br>");
}

こりゃ気持ち悪い。整数の添字と混ぜるとどうなるんだ?

var pets = new Array();

pets["Andy"] = "dog";
pets[1] = "cat";

for (name in pets) {
    document.write(name, ": ", pets[name], "<br>");
}

なんでもないかのように動く。
というか,pets[1](添字が整数)と pets[“1”](添字が文字列)を区別していないような感じ。

var pets3 = new Array();

pets3[1] = "dog";      // 整数で代入
document.write(pets3[1], "<br>");      // 整数で参照 => "dog"

pets3["1"] = "cat";      // 文字列で代入
document.write(pets3[1], "<br>");      // 整数で参照 => "cat"

やっぱり。

オブジェクト

  • JavaScript のオブジェクトは Ruby でいうクラス
  • インスタンスの生成
today = new Data();      // new コンストラクタ;
  • メソッド呼び出し
today.getDay();      // インスタンス名.メソッド名();
  • インスタンスメソッドとクラスメソッドがある。
  • インスタンス名.プロパティ名 でプロパティ参照
  • インスタンス名.プロパティ名 = 値; でプロパティを設定
  • 同じインスタンスに続けてアクセスするには with 文
with(document) {
    write("<h1>Hello!</h1>");
    write("This is JavaScript.");
}

変数

  • 宣言しなくても使えるけど,明示的に宣言するには:
var v1;
var v2, v3, v4;
var v5 = 10;      // 同時に初期化
  • 数値型,文字列型,ブーリアン型,オブジェクト型 etc.
  • リファレンス型とプリミティブ型
  • 変数名は,アルファベットか _ で始まり,2文字目以降には数字も使える。
  • 予約語は使えない。

予約語

break else new var
case finally return void
chatch for switch while
continue function this with
default if throw
delete in try
do instanceof tpeof

将来のために予約されている語もある:

abstract enum int short
boolean export interface static
bye extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public

演算子

当たり前のものは省略。

  • インクリメント(++)/デクリメント(–)。前置と後置。
  • 論理演算子: !/&&/||。not/and/or はない。
  • ビット演算子: &(論理積)/|(論理和)/^(排他的論理和)
  • シフト演算子: <<(左シフト)/>>(右算術シフト)/>>>(右論理シフト)。右算術シフトは,符号ビットは保存されるようにシフトされる。
var x = 10;
x >> 1;       // -5
x >>> 1;      // 2147483643
  • typeof演算子:値の型を調べる。

’===’ と ’==’

  • ‘===’ は型も含めて同一でなければ true にならない。
  • ‘==’ は型が違っても構わない。たとえば,数値の 10 と文字列の “10” が true になる。
var n = 10;
var s = "10";

with(document) {
    write("n = ", n, " ; type: ", typeof n, "<br>");
    write("s = ", s, " ; type: ", typeof s, "<br>");
    write("n === s : ", n === s, "<br>");      // false
    write("n == s : ", n == s, "<br>");        // true
}

故あって JavaScript に手を出す

基本事項。

  • 大文字と小文字を区別
  • ステートメントの終わりにはセミコロン;
  • // 行末までコメント
  • /* 複数行のコメント */
  • スクリプトは script タグで囲む。
  • JavaScript を認識できないブラウザのために,<!– と //–> で囲む(HTMLのコメント扱い)。
<script language="javascript" type="text/javascript">
<!--
    document.write("<hr>");
     document.write("<h1>This is JavaScirpt.<h1>");
     document.write("<hr>");
//-->
</script>
  • 関数の定義などは head エレメント内,出力などはその場所に書くのが一般的。
  • 外部ファイルにしたスクリプトは script エレメントの src 属性で指定する。
<script type="text/javascript" src="ext.js"></script>

文字列を空白で区切る

テキストファイルから入力を受け付ける時にはよく使う。あとはカンマ区切りなんかも。

import Data.Char

splitBy :: (a -> Bool) -> [a] -> [[a]]
splitBy p [] = []
splitBy p xs = a : (splitBy p $ dropWhile p $ b)
  where
    (a, b) = break p xs

splitBySpace :: String -> [String]
splitBySpace = splitBy isSpace
*Main> splitBySpace "a b c"
["a","b","c"]
*Main> splitBySpace " a b c "
["","a","b","c"]

正規表現(Text.Regex)を使えばもっとシンプルに書ける。

import Text.Regex

splitBySpace' :: String -> [String]
splitBySpace' = splitRegex (mkRegex " +")
*Main> splitBySpace' "a b c"
["a","b","c"]
*Main> splitBySpace' " a b c "
["","a","b","c",""]

……けど,ちょっと動作が違うな。
ちなみに Ruby の String#split は上の splitBySpace と同じ動作。

D:\>irb --simple-prompt
>> "a b c".split(/ +/)
=> ["a", "b", "c"]
>> " a b c ".split(/ +/)
=> ["", "a", "b", "c"]