JavaScriptにおける「オブジェクト」という用語が意図する対象をパターン別にまとめます。
「オブジェクト」という用語が使われる対象は次の3つです。
名前 | 判定用コード |
---|---|
Object 型 | arg === Object(arg) |
new Object |
Object.getPrototypeOf(arg) === Object.prototype |
Object |
arg === Object |
ECMAScript 2019 では「オブジェクト(object)」を「Object 型」を「オブジェクト」と定義しています。 これはWeb標準の仕様ですので、Object型を「オブジェクト」と呼ぶことには何の問題もありません。
member of the type Object
NOTE An object is a collection of properties and has a single prototype object. The prototype may be the null value.
なお、型の判定は typeof
演算子で可能ですが、Object 型として返しうる値のパターンが多く、typeof
演算子で対応するには Primitive 型以外を指定しなければなりません。
/**
* for ECMAScript 2019
*/
function isObject (arg) {
return arg !== null && ['undefined','boolean','number','string','symbol'].indexOf(typeof arg) !== -1;
}
しかし、ECMAScript 2020では Bigint 型が増える予定の為、"bigint"
も除外しなければならなくなります。
/**
* for ECMAScript 2020
*/
function isObject (arg) {
return arg !== null && ['undefined','boolean','number','string','symbol','bigint'].indexOf(typeof arg) !== -1;
}
Primitive型が増える度にコードを修正するのはコストがかかる為、ToObject
でObject型だけ何もしない仕様を利用すると、シンプルなコードになります。
(ToObject
は Null 型、Undefined 型を渡した際に TypeError
を返しますが、Object()
は null
, undefined
の時だけ別オブジェクトを早期リターンする為、例外は発生しません)
- 19.1.1.1 Object - ECMAScript® 2019 Language Specification
- 7.1.13 ToObject - ECMAScript® 2019 Language Specification
function isObject (arg) {
return arg === Object(arg);
}
JavaScriptが持つほぼ全てのビルトインオブジェクトは、プロトタイプチェーン(prototype-chain)上に Object,prototype
を持っています。
最も基本的なオブジェクトとして、new Object
が使われます。
(厳密には、[[Prototype]]
を持たない Object.create(null)
が最も基本的なオブジェクトですが、横道にそれるので置いておきます)
new Object
は {}
と等価であり、{}
は「オブジェクト初期化子」と呼びます(通称「オブジェクトリテラル」とも呼ばれます)。
new Object
は [[Prototype]]
上に Object.orototype
を持つ為、Object.getPrototypeOf()
で判定可能です。
(※__proto__
は将来的に削除予定のプロパティです)
console.log(Object.getPrototypeOf({}) === Object.prototype); // true
2019/11/04現在は多くのブラウザで Object.prototype.__proto__
でも判定可能ですが、Object.prototype.__proto__
はWeb標準仕様から削除された為、間もなく、使えなくなります。
console.log(new Object().__proto__ === Object.prototype); // true
Object
は new Object
で新しいオブジェクトを定義する為のコンストラクタです。
new Object
を「オブジェクト」と表現されることがありますが、これは揺らぎのある表現で誤解の元です。
例えば、次の使われ方をされた場合、
(例) new Array
は配列、new Object
はオブジェクトです。
「オブジェクト = new Object
」と読み替えることで意味が通りますが、「オブジェクト = Object型」で解釈すると意味が通りません。
new Array
も new Object
も同様に「Object 型」であり、どちらも「オブジェクト」だからです。
Object
を「オブジェクト」と表現されるサイトはあまりありませんが、そういうサイトは new Object
と Object
の区別がつきづらい為、私はほぼ信用していません。
著者に両者を区別する意図がまったく読み取れないからです。
前述の通り、「Object 型」を「オブジェクト」と表現する事に揺らぎはありません。
「オブジェクト」と呼んで間違いがないのは「Object 型」ただ一つです。 それ以外は、自分から「オブジェクト」と呼ぶのは控えたほうが誤解が少ないでしょう。
他人の文章を解読する場合は、文脈から理解に努めるしかありません。
ただし、あまりにも揺らぎ(new Object
, Object
を指す)が多い場合は、著者の知識量を疑った方が良いかもしれません。
JavaScriptで確かな情報を得たい場合は、MDN もしくは ECMAScript を参照すると良いでしょう。