JavaScript の組み込みコンストラクターって new の有無でなんとも言えない素敵動作をしてくれるので ECMAScript 5.1 を前提に動作の違いをメモっとく。仕様を眺めながら書いたもののあんまり厳密ではない。
動作表の続きに覚え方もメモっといた。
組み込みコンストラクターの new の有無での動作表
組み込みコンストラクター | new あり([[Construct]] 内部メソッド呼び出し) | new なし([[Call]] 内部メソッド呼び出し) | 備考 |
---|---|---|---|
Object | 引数を Object 型に型変換して返す。引数がなし/Null 型/Undefined 型の場合は新しい Object オブジェクトを返す。 | 同左 | 仕様上は微妙な違いがある。 |
Function | 関数の仮パラメーターとなる引数と関数のボディとなる引数で新しい Function オブジェクトを返す。 | 同左 | |
Array | 引数が Number 型で1つだけの場合はその長さで新しい Array オブジェクトを返す。それ以外の場合は引数を要素として新しい Array オブジェクトを返す。 | 同左 | |
String | 引数を String 型に型変換した値を持つ新しい String オブジェクトを返す。 | 引数を String 型に型変換して String 値を返す。 | |
Boolean | 引数を Boolean 型に型変換した値を持つ新しい Boolean オブジェクトを返す。 | 引数を Boolean 型に型変換して Boolean 値を返す。 | |
Number | 引数を Number 型に型変換した値を持つ新しい Number オブジェクトを返す。 | 引数を Number 型に型変換して Number 値を返す。 | |
Date | 引数なしの場合は現在の時刻 (UTC) を表す時間値を持つ新しい Date オブジェクトを返す。引数1つの場合は引数を日付として解析した結果の時間値を持つ新しい Date オブジェクトを返す。引数2つ以上の場合は引数を年・月・日・時・分・秒・ミリ秒とした時間値を持つ新しい Date オブジェクトを返す。 | 引数を無視して現在の時刻 (UTC) を表す String 値を返す。 | |
RegExp | 正規表現のパターンとなる引数と正規表現のフラグとなる引数で新しい RegExp オブジェクトを返す。 | 引数が RegExp オブジェクトで1つだけの場合は引数の RegExp オブジェクトを返す。それ以外の場合は正規表現のパターンとなる引数と正規表現のフラグとなる引数で新しい RegExp オブジェクトを返す。 | |
Error | 引数を String 型に型変換した値を message として持つ新しい Error オブジェクトを返す。 | 同左 |
型変換系
new なしの型変換でまとめると覚えやすい。
var o = Object(x);
var s = String(o);
var b = Boolean(o);
var n = Number(o);
リテラル系
リテラルや初期化子があるものでまとめると覚えやすい。
var o = new Object(); // var o = {};
var f = new Function(); // var f = function() {};
var a = new Array(); // var a = [];
var r = new RegExp(); // var r = /(?:)/;
new なしでも動作がほぼ同じになるということも覚えておこう。
var o = Object(); // var o = {};
var f = Function(); // var f = function() {};
var a = Array(); // var a = [];
var r = RegExp(); // var r = /(?:)/;
実装ではリテラルや初期化子を使用するのがいいと思う。
ラッパーオブジェクト系
プリミティブ値のオブジェクト(ラッパーオブジェクト)でまとめると理解しやすい。
var s = new String("");
var b = new Boolean(false);
var n = new Number(0);
自然なオブジェクト系
new ありが自然なオブジェクトでまとめると覚えやすい。(無理矢理感は否めないまとめ方……。)
var d = new Date();
var e = new Error();
その他系
new なしの Error()
はショートハンドとしての利用価値はありそうだけど、new Error()
でいいんじゃないだろうか。コーディング規約にもよりそうだけど。
var e = Error();
new なしの Date()
は ECMAScript 仕様随一の Supercalifragilisticexpialidocious な動作をする。どうしてこうなった感がすごい。
var d = Date();
参考文献
ECMA-262 Edition 5.1を読む