オブジェクト (Object)

オブジェクト生成演算子 (new)

new constructor [ ( [arguments] ) ]
new - JavaScript | MDN

new演算子はオブジェクトを生成し、そのオブジェクトのコンストラクタ関数を呼び出します。なお次のように、オブジェクトリテラルでプロパティを指定せず生成しても、同様の結果を得られます。

var obj = {};

newの省略

オブジェクトによっては、new演算子を省略してもオブジェクトを生成できます。また引数がない場合には、かっこを省略できます。

obj = new Object();
obj = Object(); // これも可
obj = Object;   // これでも可

たとえばObjectオブジェクトは、new演算子の有無にかかわらず同じ結果が返されます。しかしオブジェクトによっては異なる結果を返すため、new演算子の省略には注意が必要です。

new演算子の有無による戻り値の違い
オブジェクト newあり newなし
Object Objectオブジェクト
Array Arrayオブジェクト
String Stringオブジェクト 文字列
Number Numberオブジェクト 数値
Date Dateオブジェクト 現在の日時を表す文字列
(引数は無視される)

プロパティ

オブジェクトのプロパティは、基本的に変数と同じものです。また、どのようなデータ型もプロパティに設定できます。

var obj = {
    a:1,     // 数値
    b:'abc', // 文字列
    c:true,  // 論理値
    d:{},    // オブジェクト
    e:[],    // 配列
    f:function(){} // 関数
};

プロパティの作成

オブジェクトの作成とそのプロパティの作成には複数の方法が存在し、次の7つのコードは同一の結果を得ます。

サンプルコード 説明 プロパティ名
の指定方法
var obj = new Object();
obj.foo = 'bar';
Objectインスタンスを作成し、未定義のプロパティを定義。 識別子
var obj = new Object();
obj[ 'foo' ] = 'bar';
ブラケット表記法でプロパティを定義。 文字列
var a = 'foo';

var obj = new Object();
obj[ a ] = 'bar';
プロパティ名を変数として、ブラケット表記法でプロパティを定義。 変数
var obj = Object();
obj.foo = 'bar';
new演算子を省略し、Objectインスタンスを作成。 識別子
var obj = { foo: 'bar' };
オブジェクトリテラルとして、プロパティを初期化して作成。 識別子
var obj = { 'foo': 'bar' };
プロパティ名を文字列で指定。 文字列
var obj = {};
obj.foo = 'bar';
オブジェクトリテラルとして、プロパティを設定せず作成。 識別子
JavaScript の配列と連想配列の違い - IT戦記

プロパティの作成は、組み込みのオブジェクトに対しても行えます。それをprototypeプロパティに適用することで、組み込みオブジェクトにメソッドを追加できます。

オブジェクトにプロパティを追加するときには、オブジェクトリテラルは使用できません。

プロパティと連想配列

オブジェクトのプロパティへは、メンバー演算子のブラケット表記法 (Bracket notation) を用いてアクセスできるため、これを利用すれば連想配列としてプロパティを使用できます。たとえば次の3つは、同一のプロパティを示します。メンバー演算子 - JavaScript | MDN

image.width;
image[ 'width' ];
var a = 'width';
image[ a ];

プロパティ名を変数で指定できるため、これを活用することでアクセスするプロパティを動的に変更することも可能です。また、プロパティ名 (識別子) に使用できない文字が使えるようになります。たとえばobj.@は不可ですが、obj[ '@' ]は可能です。

オブジェクトリテラル (オブジェクトイニシャライザ)

オブジェクトの生成時に、プロパティを初期化できます。オブジェクト初期化子の使用 - JavaScript | MDN Object initializer - JavaScript | MDN

{ propertyName:value, propertyName:value, ... }

最後のプロパティの後にカンマ (,) を付けると、IE8より前では「識別子、文字列または数がありません。」としてスクリプト エラーとなります。IE8以降やFirefoxでは問題となりませんが、クロスブラウザとするためには最後にカンマを付けるべきではありません。同様の問題は配列リテラルにもあります。

次の2つのコードは同じ結果となります。

var point = new Object();
point.x = 1;
point.y = 2;
var point = { x: 1, y: 2 };

しかし次のように、プロパティが設定されたオブジェクトに、オブジェクトリテラルを設定するのは間違いです。

var point = { x: 1 };
point = { y: 2 };

これでは{y: 2}{x: 1}を上書きするため、プロパティxが削除されてしまいます。

オブジェクトリテラルは、プロパティの初期化に使用するものです。

プロパティの存在確認 (in演算子)

in演算子は、指定されたプロパティがオブジェクトに存在する場合にtrueを返します。

property in objectName
in - JavaScript リダイレクト 1 | MDN

propertyで、確認するプロパティの名前を文字列で指定します。

var obj = { a: 1 };
'a' in obj; // true
'b' in obj; // false

ただし対象のオブジェクトが配列のときには、その要素のインデックスを数値で指定します。

var arr = [ 10, 20 ];
0 in arr; // true
1 in arr; // true
2 in arr; // false

プロパティの存在は、それがundefinedを返すかどうかでも判定できます。

var obj = { a: 1 };
obj.a; // 1
obj.b; // undefined

var arr = [ 10, 20 ];
arr[ 0 ]; // 10
arr[ 1 ]; // 20
arr[ 2 ]; // undefined

ただしプロパティにundefinedが設定されていると、プロパティが存在するにも関わらずundefinedが返されます。一方で、in演算子ならば適切に判定できます。

var x;
var obj = { a: 1, b: x };

'a' in obj; // true
'b' in obj; // true

obj.a; // 1
obj.b; // undefined <-- obj.bは存在している

この相違は、プロパティの存在によってif文で処理を分けるような場合に大きく影響します。

if( 'a' in obj )
{
    // obj.aが存在している場合に、実行される
}

if( obj.a )
{
    // obj.aが存在しており、その値が
    //  true
    //  0以外の数値
    //  空文字以外の文字列
    //  オブジェクト (配列を含む)
    // のいずれかである場合に、実行される
}

よって厳密な判定が必要な場合には、in演算子を用いるべきです。ちなみにオブジェクト自身の存在は、未定義の判定方法で調べられます。

プロパティの一覧表示

あるオブジェクトのインスタンスに対してfor ... inでループ処理することで、そのオブジェクトで定義されているプロパティを一覧できます。またそのプロパティ名をキーとすることで、そのインスタンスにおけるプロパティの値も取得できます。

function ShowProperties( object )
{
    var property = [];
    for( var propertyName in object )
    {
        var propertyValue = object[ propertyName ];
        property.push( propertyName + ' : ' + propertyValue );
    }
    window.alert( property.join( '\n' ) );
}

なお組み込みプロパティの多くは、この方法では取得できません。それは、それらのプロパティにDontEnum属性が設定されているからです。ECMAScript DontEnum attribute | MDN

またfor ... inでは、取得する順序は指定できません

取得例

たとえば上記の関数に対してwindow.screenを引数にして呼び出すと、

top : 120
height : 768
width : 1024
left : -1024
pixelDepth : 24
colorDepth : 24
availWidth : 1024
availHeight : 768
availLeft : -1024
availTop : 120

のような結果を取得できます。なおこれはFirefoxの場合であり、結果はブラウザによって異なります。

プロパティの削除 (delete演算子)

オブジェクトのプロパティは、delete演算子によって削除できます。

delete expression
delete - JavaScript | MDN
var obj = { a: 1,b: 2 };

delete obj.a; // trueが返され、objは{ b=2}となる
delete obj.a; // trueが返され、何も行われない
delete obj;   // falseが返され、何も行われない

deleteは配列の要素にも適用できます。しかし要素は削除できても、配列の大きさは変化しません。

var p = [ 1, 2, 3 ];
delete p[ 1 ]; // trueが返され、pは[1, undefined, 3]となる

alert( 0 in p ); // true
alert( 1 in p ); // false
alert( 2 in p ); // true
alert( 3 in p ); // false

var文を用いず宣言された変数は、その実体はグローバルオブジェクトのプロパティのため、これもdeleteで削除できます。

a = 1;     // グローバルオブジェクトのプロパティ
var b = 1; // 変数

delete a; // trueが返され、aは削除される
delete b; // falseが返され、何も行われない

グローバルプロパティ (Global Property)

null値

nullとは、オブジェクトがないことを表すオブジェクト型の値です。

用途 変換後の値
論理コンテキスト false
数値コンテキスト 0
文字列コンテキスト null

数値との比較

数値コンテキストではnullは0と解釈されるため、1より小さく、-1より大きいです。

結果
null < 1
true
null > 1
false
null < -1
false
null > -1
true

また0以下であるが0より小さくはなく、0以上であっても0より大きくはありません。

結果
null < 0
false
null <= 0
true
null >= 0
true
null > 0
false

しかし0とは等値でも同値でもありません。

結果
null == 0
false
null === 0
false

グローバルオブジェクト (Global Objects)

  • Array
  • Boolean
  • Date
  • Error
    • EvalError
    • RangeError
    • ReferenceError
    • SyntaxError
    • TypeError
    • URIError
  • Function
  • Math
  • Number
  • Object
  • RegExp
  • String
  • Window (クライアントサイドJavaScriptの場合)
Global Objects - JavaScript | MDN

参考

参考書

  • JavaScript 第5版 [オライリー・ジャパン] David Flanagan
    7章「オブジェクトと配列」