7章 データ処理
- 配列と正規表現は重要
配列
- p187 順序のある要素の集まり
- JavaScriptの配列はオブジェクトなので、要素の追加、書き換えができる
JavaScriptの配列
- []で、配列要素をカンマ区切りすることで生成可能
- []のみの場合、空の配列になる。空の配列に後から要素を追加するのはJavaScriptで一般的な手法
- p188 要素を飛ばすことが可能。飛ばした要素はundefinedになる
- ECMAScriptの仕様では、要素の最後をカンマで終えることは許容されるが、IEなどで不具合があるのでやらない方がよい
配列の要素アクセス
- p189 途中の要素を飛ばして要素を追加すると、間の要素はundefinedになる
配列の長さ
- .lengthで要素の長さが得られる
- データが入っている数ではなく、最後の要素までの数
- p190 lengthの値を小さくすると、要素から外れたデータは破棄される
配列の要素の列挙
- for文を使って、lengthの回数ループしてアクセスする
- for inでプロパティを取り出すことは可能だが、順が不定になるので推奨されない
- p191 ECMAScript5のArrayクラスではforEach()メソッドが使える。要素を順に取り出しながら、コールバック関数を呼び出す
- コールバック関数には、要素、インデックス値、配列オブジェクトの3つが引数として渡される
- p192 forEachの第2引数には、thisとして利用するオブジェクトを指定できる
配列の長さの上限
- p191 ECMAScriptでは、2の32乗が上限
- 2の32乗を越える数値の要素も使えるが、識別子として追加される。lengthでは対応できないので注意
多次元配列
- 配列の要素に配列を指定することで可能
- arr[外側][内側]でアクセスできる
配列はオブジェクト
Arrayクラス
- newによる生成とArray呼び出しは配列では同じ
- p195 Arrayクラスのプロパティ
- prototype
- length
- isArray(引数)…引数のものが配列インスタンスならtrue
- Array.prototypeオブジェクトのプロパティ一覧(気になったものを抜粋)
- concat…配列に引数の要素を連結した新しい配列を生成
- every(callbackfn[,thisArg])…要素を順に取り出してコールバック呼び出し。コールバックがfalseを返すと終わり
- filter(callbackfn[,thisArg])…要素を順に取り出してコールバック呼び出し、コールバックがtrueの要素を集めた新しい配列を返す
- forEach(callbackfn[,thisArg])…要素を順に取り出してコールバック
- indexOf(検索値[,最初のインデックス])…検索値に最初に一致する要素のインデックスを返す
- join(セパレータ)…配列の要素間にセパレータを挟んだ文字列を生成
- lastIndexOf
- map(コールバック[,thisArg])…要素を順にコールバックを呼び出し、戻り値の要素を新しい配列にして返す
- pop…最後の要素を削除して返す
- push(要素)…配列の末尾に要素を追加
- reduce(コールバック[,初期化値])…配列の各要素と直前の関数呼び出し結果を引数にして順にコールバックを呼び出す。最後の関数呼び出し結果を返す。要素の総括を求める
- reduceRight(コールバック[,initialValue])…reduceの逆順処理
- reverse
- shift…配列の先頭の要素を削除してから返す
- slice(start,end)…インデックスのstartからendまでの要素を新しい配列にして返す
- some(コールバック[,thisArg])…everyで、trueを返すと終了
- sort(比較関数)
- splice(start,delCount[,item0,item1,…])…インデックスstartからdelCountkの要素を削除。itemが指定されていたら、削除した場所にそれらの配列を挿入する
- toLocaleString()
- toSource()…独自拡張。評価結果が配列生成になる文字列を返す
- toString()…配列を文字列値に変換
- unshift([item0,item1,…])…引数を配列の先頭に追加
- Arrayクラスのインスタンスプロパティは、0以上の整数値とlength
配列オブジェクトの意味
- p196 配列はオブジェクトだが、その逆は成立しない
- オブジェクトを生成して、配列的な要素を追加しても、要素を追加するだけでlengthが増加するような振る舞いが実装されない
- 配列とオブジェクトの違いは、自動的に要素数を操作したり、forEach、インデックス順を考えた操作などにある
配列のイディオム
- ソート
- sortの引数を省略すると、文字列の昇順にソート
- p197 並び替えは昇順で行われる。並び替え方を決める関数は、引数を2つ取り、お互いの差を値で返す。昇順で並び替えたい場合は、第1引数-第2引数をreturnすればよい。第1引数の方が大きいと正になり、その場合は引数を入れ替える
- sort関数は、与えた配列の順番を入れ替える。新しい配列を生成することはしないので、破壊的メソッドとなる
- 配列を使った文字列生成
- 文字列を結合する際は、+で結合するよりも、配列にpushで追加していき、最後にjoinすると速いと言われている。実装によるので必ずしもそうとは限らない
- p198 配列のコピー
- 代入は、参照の代入なのでコピーにはならない
- [].concat(arr)や、arr.slice(0,arr.length)でコピーできる
- p199 deepコピーは、要素内のオブジェクトもコピーする
- shallowコピーは、要素のコピーのみで、要素の参照先などは参照のまま
- deepコピーは自分で実装する必要がある
- 要素の削除
- deleteで削除した場合、削除したインデックスは空のまま隙間が残る
- spliceで削除すると、削除した場所が詰められる
- フィルタ処理
- p200 mapやfilterなどを利用すると、配列のデータをメソッドチェインをしながら処理していくことができる。シンプルに書くことができ、非破壊的な処理になるので行儀もよい
配列の内部
- 確保したメモリが連続のメモリに割り当てられるかどうかは実装依存であるが、ある程度頑張っている。過度に心配しなくてもよい
配列風のオブジェクト
- p201 argumentsオブジェクトなど、要素をfor文で列挙できるので同じように使える
- DOMのAPIに多い
- p202 JavaScript独自拡張だが、Array.join(配列風オブジェクト,',')などが使える可能性がある
- Array.prototype.join.call(fake_all,',')で、thisを配列風オブジェクトにして実行だとより汎用的
イテレータ
- 繰り返しに特化したオブジェクト
- IteratorクラスはJavaScript独自拡張のもの
- .nextで次の要素に切り替える機能が提供される
- あまり使い所はない
ジェネレータ
- p204 JavaScript独自拡張
- 関数内でyieldを呼び出す(yieldはJavaScriptの予約語)
- p205 yieldがあると、その場では実行されず、イテレータオブジェクトが返される
- 返されたオブジェクトのnextを呼ぶと1回分のループが処理される
配列の内包
- p206 JavaScript独自拡張
- ジェネレータを使って配列を生成できる
- p207 for each で、ジェネラータを呼び出すコードを書き、それを配列リテラルで囲む
JSON
- 文字列、数値、ブーリアン、nullのデータの基本型4つ、オブジェクトと配列の構造化型の2つを持てる
- 文字列にシングルクォーテーションは使えない。デフォルトエンコードはUTF-8
- 数値。10進数のみ
- プロパティ名は文字列表記のみ
JSON文字列
- p208 以前はeval関数で変換していた
- JSON文字列は、JavaScriptのリテラル式となっているので、実行すればオブジェクトが得られるが、セキュリティの問題と、表記の問題があった
- ECMAScript5で標準化。その前はjson2.jsなどのライブラリがあった
JSONオブジェクト
- JSONを扱うためのオブジェクトで、コンストラクタ呼び出しはできない
- parse(text[,reviver])…textをJavaScriptオブジェクトに変換。第2引数を指定すると、プロパティ単位でコールバックとして呼び出し、返り値がプロパティ値にできる
- stringify(value[,replacer[,space]])…valueをJSON文字列に変換。replacerはプロパティ単位で呼ばれるコールバックで、返り値がプロパティ値になる。spaceは出力時のインデント用文字列
日付処理
- p210 1970年1月1日からの経過ms
- JavaScriptの数値は正負53ビットで表せるので十分(285616年まで大丈夫)
- 上記のエポック値
- Dateクラスで月処理、週処理、曜日判定など
- 文字列。利用者とのやりとりやネットワーク交換用
- 年月日などの数値。利用者とのやりとり
Dateクラス
- p211 月は0からなので注意
- now()で、エポック値を得られる
- UTC()で、年月日、HMSmsを指定して、そのエポック値を得る
- Date.prototypeオブジェクトのプロパティ一覧
正規表現
正規表現とは
正規表現の用語
- パターン…探したい規則
- 入力シーケンス…パターンを探す対象文字列
- p214 マッチ…入力シーケンスの中で、パターンが見つかること
正規表現の文法
正規表現プログラミング
- p218 execは、マッチ結果を配列で返す。マッチしない場合はnullを返す
- testは、マッチ結果をtrue、falseで返す
- execの戻り値は、最初にマッチに該当した文字列、それ以降に個別の要素が入る
- p219 gフラグが付いていると、連続呼び出しで継続して調査できる。見つからないとnullが返るので、nullが返るまでループさせる
文字列オブジェクトと正規表現オブジェクト
- 文字列オブジェクトのメソッドで、正規表現を引数にとるメソッドがある
- match、replace、search、splitの4つ
- p220 replaceの第1引数に正規表現でグループ化を使うと、第2引数の文字列の中でグループ前方参照を示す$1や$2という文字列を使える
- replaceで使える前方参照の一覧
- $&…マッチした文字列
- $数字…1からの数字で、見つかったうちの何番目のグループ化を表す
- $`…マッチの前の文字列
- $'…マッチの後ろの文字列
- replaceの第2引数にコールバック関数を渡すと、マッチする度にコールバックを呼び出して戻り値で置換する
- p221 matchメソッドは、マッチした部分文字列の配列を返す
- gフラグを設定すると、マッチした全ての部分文字列を配列にする
- gフラグがないと、RegExp.execと同じ
ECMAScript5のstrict mode
- p222 コードの先頭行に以下のディレクティブを書く
'use strict'; "use strict";
- 関数の先頭行に書くと、その関数内で有効になる
- strict modeに未対応の場合は、ただの文字列として無視される