new constructor [ ( [arguments] ) ]new - JavaScript | MDN
new演算子はオブジェクトを生成し、そのオブジェクトのコンストラクタ関数を呼び出します。なお次のように、オブジェクトリテラルでプロパティを指定せず生成しても、同様の結果を得られます。
var obj = {};
オブジェクトによっては、new演算子を省略してもオブジェクトを生成できます。また引数がない場合には、かっこを省略できます。
obj = new Object(); obj = Object(); // これも可 obj = Object; // これでも可
たとえばObjectオブジェクトは、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.prop = 'abc'; |
Objectインスタンスを作成し、未定義のプロパティを定義。 | 識別子 |
var obj = new Object(); obj[ 'prop' ] = 'abc'; |
ブラケット表記法でプロパティを定義。 | 文字列 |
var a = 'prop'; var obj = new Object(); obj[ a ] = 'abc'; |
プロパティ名を変数として、ブラケット表記法でプロパティを定義。 | 変数 |
var obj = Object(); obj.prop = 'abc'; |
new演算子を省略し、Objectインスタンスを作成。 | 識別子 |
var obj = { prop: 'abc' };
|
オブジェクトリテラルとして、プロパティを初期化して作成。 | 識別子 |
var obj = { 'prop': 'abc' };
|
プロパティ名を文字列で指定。 | 文字列 |
var obj = {};
obj.prop = 'abc';
|
オブジェクトリテラルとして、プロパティを設定せず作成。 | 識別子 |
プロパティの作成は、組み込みのオブジェクトに対しても行えます。それを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演算子は、指定されたプロパティがオブジェクトに存在する場合にtrueを返します。
property in objectNamein - 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 expressiondelete - 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が返され、何も行われない
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 |