0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[JavaScript] newが使える組み込みオブジェクト / 使えない組み込みオブジェクトの内部構造

Posted at

概要

JavaScript の組み込みオブジェクトには、new を使ってインスタンスを生成するものと、
new を使わずそのまま利用するものが存在します。
これらの違いは、メソッドがどこに定義されているかという点に集約されます。

つまり、

new を使える組み込みオブジェクトと、new を使えない組み込みオブジェクトでは、
メソッドが定義されている「場所」が決定的に異なる

ということです。

この記事では、

  • Date / Map のような new を使える関数オブジェクト
  • JSON / Math のような new を使えない通常のオブジェクト

について、構造レベルでの違いを整理します。

目次

全体像

① new を使える組み込みオブジェクト(Date / Map など)
   → メソッドは prototype に定義されている(インスタンスメソッド)

② new を使えない組み込みオブジェクト(JSON / Math など)
   → メソッドはオブジェクト自身に定義されている(static メソッド)

new を使える組み込みオブジェクトの構造

Date / Map の正体

typeof Date; // "function"
typeof Map;  // "function"
  • 関数オブジェクト
  • [[Construct]] を持つ
  • new が使える
  • prototype を持つ

これらは コンストラクタとして設計された関数オブジェクトです。

Map の内部構造

Map              // コンストラクタ(関数オブジェクト)
 ├─ prototype ──▶ Map.prototype
 │                 ├─ set()
 │                 ├─ get()
 │                 ├─ has()
 │                 └─ delete()

実際の使用例

const map = new Map();
map.set("a", 1);

このとき JavaScript は次の順で処理します。

  1. map 自身に set プロパティがあるかを確認
  2. map.__proto__ === Map.prototype を参照
  3. Map.prototype.set を実行
  4. thismap を指す

この結果、データ(状態)は map インスタンスに保存されます


prototype に定義されていることの確認

Map.prototype.hasOwnProperty("set"); // true
map.hasOwnProperty("set");           // false
  • set はインスタンス自身には存在しない
  • Map.prototype に定義されている

Date も同様の構造

Date.prototype.getFullYear();
Date.prototype.toISOString();
const d = new Date();
d.getFullYear(); // prototype メソッド

なぜ prototype に置くのか

  • 全インスタンスで同じ関数を共有できる
  • メモリ効率が良い
  • オブジェクト指向設計に沿っている
1000 個の Map インスタンス
→ set / get 関数は 1 つだけ

new を使えない組み込みオブジェクトの構造

JSON / Math の正体

typeof JSON; // "object"
typeof Math; // "object"
  • 通常のオブジェクト
  • インスタンスを生成しない
  • prototype を使った設計ではない

JSON の内部構造(概念)

JSON
 ├─ stringify()
 ├─ parse()

使用例

JSON.stringify(obj);
JSON.parse(str);
  • JSON 自身が完成形
  • this を使わない
  • 状態を持たない

Math も同様

Math.max(1, 2, 3);
Math.random();
Math.hasOwnProperty("max"); // true

このように、メソッドは prototype ではなく、オブジェクト自身に定義されています

両者の違いの整理

観点 Date / Map JSON / Math
typeof function object
new 使用可能 使用不可
prototype あり なし
メソッドの定義場所 prototype オブジェクト自身
this インスタンス 使用しない
状態 インスタンスに保持 なし

Map.set はどこに定義されているのか

Map 自体に set が定義されているわけではありません。

Map.set; // undefined

実際に定義されているのは prototype 側です。

Map.prototype.set; // function

正しい理解は次の通りです。

Map は「設計図」
set / get は Map.prototype に定義されている
実際のデータは map(インスタンス)に保存される

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?