私の歴史と今

振り返ると恥ずかしくなるのが私の歴史。だけどそのときは真面目に書いていた訳でね。そんな今の私を書いていく。

JavaScript 第5版 7章 オブジェクトと配列

オブジェクト:値に名前を付けたものの集まり
配列:値にインデックスを付けたものの集まり

7.1 オブジェクトの生成

オブジェクトリテラル

var obj = {};  // 空のオブジェクト → new Object()と同じ
var ken = {name:'ken', age:31}; 

7.2 オブジェクトのプロパティ

ドット演算子(.)でアクセスできる。左辺は、オブジェクトに評価できるものであれば何でもいい。

var obj = {x:1, y:2};
alert(obj.x);                   // 1
alert({x:1, y:2}.x);            // 1
alert(new Object().toString()); // [object Object]

オブジェクトのプロパティは、代入するだけで追加できる。

var obj = {x:1, y:2};
obj.z = 3;
alert(z);  // 3

オブジェクトのプロパティの調査は、for/in文で可能。ただし、組み込みオブジェクトのプロパティは一部調査不能。自作オブジェクトは調査可能。

var obj = {x:1, y:2};
for(var prop in obj){
  alert(prop);
}

特定プロパティの存在確認はin演算子で可能。

var obj = {x:1, x:2};
alert('x' in obj);  // true
alert('y' in obj);  // true
alert('z' in obj);  // false

特定プロパティが存在しており、undefinedでもnullでもない場合に処理を実行したい場合は、下記のようになる。

if(obj.hoge){
  obj.hoge();
}

プロパティの削除は、delete演算子を用いる。

var obj = {x:1, y:2};
alert('x' in obj);  // true
delete obj.x;
alert('x' in obj);  // false

7.3 連想配列としてのオブジェクト

オブジェクトのプロパティにアクセスする方法は2つ。ドット演算子(.)を使う方法と、配列演算子([])を使う方法。

var obj = {x:1, y:2};
alert(obj.x);    // 1
alert(obj['y']); // 2

配列演算子を使う場合は、オブジェクトを連想配列として扱っている。JavaのHashMapのようなもの。値に名前を付けて、その名前でアクセスする。名前を文字列で扱えるので、プログラムの柔軟性が増す。

7.4 Objectのプロパティとメソッド

すべてのオブジェクトはObjectクラスのプロパティを継承している。

7.4.1 constructorプロパティ

すべてのオブジェクトはconstructorプロパティに自身を作成したコンストラクタの参照を持ってるんだってよ!

var Person = function(name){
  this.name = name;
};
var ken = new Person('ken');
alert(ken instanceof Person);       // true
alert(ken.constructor === Person);  // true おおすげー!

ってことは、更にこんなことができるのか。

ver yamamoto = new ken.constructor('yamamoto');
alert(yamamoto instanceof Person);       // true
alert(yamamoto.constructor === Person);  // true おおー

利用イメージはつかないけど、感動した。
しかも、constructorプロパティは、instanceof演算子の判断材料になってるらしい。でもconstructorプロパティを上書きしたらどうなる?

yamamoto.constructor = Date;
alert(yamamoto.constructor === Date);   // true
alert(yamamoto instanceof Person);      // true  あれれ? constructorは関係ないのか
alert(yamamoto instanceof Date);        // false あれれ? constructorは関係ないのか
alert(new yamamoto.constructor() instanceof Date);   // true
alert(new yamamoto.constructor() instanceof Person); // true

ということは、instanceof演算子はconstructorプロパティの値を参照してないと。なーんだ。

7.4.2 toString()メソッド

7.4.3 toLocaleString()メソッド

こんなのあるんだ。

7.4.4 valueOf()メソッド

7.4.5 hasOwnProperty()メソッド

継承ではない独自プロパティを持つ場合はtrue。継承って何だっけ・・・。コンストラクタを呼び出した後に追加したものがtrueになるのかな。

var Obj = function(){};
Obj.prototype={x:1, y:2};
var obj = new Obj();
obj.z = 3;
alert(obj.hasOwnProperty('x')); // false
alert(obj.hasOwnProperty('y')); // false
alert(obj.hasOwnProperty('z')); // true

7.4.6 propertyIsEnumerable()メソッド

hasOwnProperty()メソッドでtrueになり、かつ、for/inループで調査できるものがtrueになるメソッド

7.4.7 isPrototypeOf()メソッド

へー、だね。

alert(Function.prototype.isPrototypeOf(Object));

7.5 配列

配列とは、値にインデックスを付けてまとめたもの。値は要素という。要素にはインデックスを用いてアクセスできる。配列もオブジェクトの1つだけど、通常、オブジェクトと配列は分けて考える。
配列の作成方法
配列リテラル

// 異なる型が混在していてもいい
var a = [1, '2', true, new Object()];

引数なしArrayコンストラクタ

// var a = []; と同じ
var a = new Array();

要素で初期化するArrayコンストラクタ

// var a = [1, 2, 3]; と同じ
var a = new Array(1, 2, 3);

素数を指定するArrayコンストラクタ

// var a = [, , ]; と同じ?
var a = new Array(3);

7.6 配列の要素の読み書き

[]演算子を使用して各要素にアクセスする。

// 最初の要素は、インデックス「0」
var a = [1, 2, 3];
alert(a);  // 「1」と表示

配列はオブジェクトなので、インデックス以外にもプロパティを定義できる。

var a = [1, 2, 3];
a.name = 'あれー';
alert(a.name);

配列に要素数は固定ではない。

var a = new Array(1);
alert(a.length);  // 1
a[1] = 2;
alert(a.length);  // 2

メモリ割り当ては、格納済み要素のみ。

var a = [1];
a[100] = 100; // 要素[0]-[99]に関してはメモリ割り当てされていない。

配列のようなオブジェクト

var obj = new Object();
obj[0] = 1;  // '0'プロパティを定義しているだけ。

配列要素の削除方法は、shift(), pop(), splice()など。
配列の長さは、lengthプロパティ。lengthよりも大きい要素にデータを格納すると、lengthプロパティの値は自動更新される。要素数未満のlengthを設定すると、配列が小さくなる。要素以上のlengthを設定すると、配列が拡張され、拡張された部分は未定義値になる。
多次元配列はサポートしていないが、配列の配列はOK。

7.7 配列のメソッド

    1. join() 各要素を引数で連結して文字列を作成する
    2. reverse() 各要素を逆順にする
    3. sort() 各要素をソートする
    4. concat() 配列に配列を連結する
    5. slice() サブ配列の作成
    6. splice() 配列の切り取り
    7. push(), pop() 最後の要素の追加削除
    8. unshift(), shift() 最初の要素の追加削除
    9. toString(), toLocaleString()
    10. indexOf(), lastIndexOf(), forEach(), filter()などはJavaScript1.6で追加。便利だー。

7.8 配列のようなオブジェクト

配列とオブジェクトの異なる点は

    1. 新しい要素を追加するとlengthプロパティの値が自動的に更新される
    2. lengthプロパティを変更すると配列の要素が追随する。

配列のようなオブジェクトは簡単に作れる。

var obj = {};
obj[0] = 1;
obj[1] = 2;
obj.length = 2;