| この記事の要点 |
- ビルトインオブジェクトはランタイムが標準で提供する組込型 (Object / Array / Map / Promise / Symbol など)
- ES2015 で Map / Set / Promise / Symbol / WeakMap / WeakSet が追加され近代化
- ES2022 で Array.prototype.at() / Object.hasOwn() 追加
- ES2023 で findLast / findLastIndex / toReversed / toSorted 等の非破壊メソッド追加
- 新提案は TC39 の Stage 0-4 で管理。Stage 3 以降は使い始めても良い目安
|
ビルトインオブジェクト一覧
| カテゴリ | オブジェクト | 用途 |
| 基本 | Object, Function, Boolean, Symbol | すべての基底 / 関数 / 真偽値 / 一意キー |
| 数値 | Number, BigInt, Math | 64bit 浮動小数 / 任意精度整数 / 数学関数 |
| 文字列 | String, RegExp | 文字列 / 正規表現 |
| 日時 | Date | 日時操作 (ただし Temporal で置換予定) |
| コレクション | Array, Map, Set, WeakMap, WeakSet | 順序付き / キー付き / 重複なし |
| 非同期 | Promise | 非同期処理の合成 |
| シリアライズ | JSON | JSON.parse / JSON.stringify |
| 例外 | Error, TypeError, RangeError | throw できる例外型 |
| バイナリ | ArrayBuffer, Uint8Array, DataView | 低レベルバイト列 |
| 反復 | Iterator, Generator | for...of 対象 |
Object: すべての基底
const user = { name: 'Taro', age: 30 };
Object.keys(user); // ['name', 'age']
Object.values(user); // ['Taro', 30]
Object.entries(user); // [['name','Taro'], ['age',30]]
Object.assign({}, user, { age: 31 }); // マージ
Object.freeze(user); // 不変化
Object.hasOwn(user, 'name'); // ES2022, true (in より安全)
// Spread (ES2018)
const copy = { ...user };
const merged = { ...user, age: 31 };
// 分割代入
const { name, age } = user;
const { name: userName } = user; // リネーム
Array: 順序付きコレクション
const arr = [1, 2, 3, 4, 5];
// 反復系 (高階関数)
arr.map(x => x * 2); // [2, 4, 6, 8, 10]
arr.filter(x => x % 2 === 0); // [2, 4]
arr.reduce((acc, x) => acc + x, 0); // 15
arr.forEach(x => console.log(x));
// 検索
arr.find(x => x > 3); // 4
arr.findIndex(x => x > 3); // 3
arr.includes(3); // true
arr.at(-1); // 5 (ES2022, 負数で末尾から)
// ES2023 非破壊版
arr.toReversed(); // [5,4,3,2,1] (元は不変)
arr.toSorted((a, b) => b - a); // 降順
arr.toSpliced(1, 2); // [1, 4, 5]
arr.findLast(x => x < 4); // 3
arr.findLastIndex(x => x < 4); // 2
// 破壊版 (元配列を変える)
arr.push(6); // 末尾追加
arr.pop(); // 末尾削除
arr.sort(); // ソート (デフォルトは文字列順 注意)
Map / Set: ES2015 で追加されたコレクション
// Map: キーに任意の型 (オブジェクトも可)
const m = new Map();
m.set('name', 'Taro');
m.set({ id: 1 }, 'user1'); // ★ Object でもキーにできる
m.get('name'); // 'Taro'
m.has('name'); // true
m.size; // 2
for (const [k, v] of m) { ... }
// vs Object (Map の利点)
// - キーの順序が保証される
// - サイズが size プロパティで取れる
// - プロトタイプ汚染がない
// - 任意の型をキーに使える
// Set: 重複なし配列
const s = new Set([1, 2, 2, 3]); // {1, 2, 3}
s.add(4);
s.has(2); // true
s.size; // 4
// 配列の重複排除イディオム
const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
// WeakMap / WeakSet: ガベージコレクションされる
// キーが他で参照されなくなったら自動削除
const wm = new WeakMap();
wm.set(domNode, metadata); // domNode が消えたら自動で削除
Promise: 非同期処理の合成
// 基本
const p = fetch('/api/users')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err))
.finally(() => console.log('done'));
// 並列待ち
Promise.all([fetch('/a'), fetch('/b')]) // 1つでも失敗するとreject
Promise.allSettled([fetch('/a'), fetch('/b')]) // 全部の結果を受け取る
Promise.race([fetch('/a'), fetch('/b')]) // 最初に解決した1つ
Promise.any([fetch('/a'), fetch('/b')]) // 最初の成功 (ES2021)
// async/await (Promise の糖衣構文)
async function loadUsers() {
try {
const res = await fetch('/api/users');
return await res.json();
} catch (e) {
console.error(e);
}
}
Symbol: 一意キー
// 衝突しないオブジェクトキーを作る
const id = Symbol('id');
const user = { name: 'Taro', [id]: 1 };
user[id]; // 1
Object.keys(user); // ['name'] (Symbol は列挙されない)
// Well-known Symbol (組込フック)
class Range {
constructor(start, end) { this.start = start; this.end = end; }
[Symbol.iterator]() { // for...of の挙動を定義
let cur = this.start;
const end = this.end;
return {
next: () => cur <= end
? { value: cur++, done: false }
: { value: undefined, done: true }
};
}
}
for (const i of new Range(1, 5)) console.log(i); // 1 2 3 4 5
JSON: シリアライズ
const obj = { name: 'Taro', items: [1, 2, 3] };
const json = JSON.stringify(obj); // 文字列化
const json2 = JSON.stringify(obj, null, 2); // 整形 (インデント 2)
const back = JSON.parse(json); // パース
// undefined / function / Symbol は消える
JSON.stringify({ a: 1, b: undefined, c: () => {} });
// → '{"a":1}'
// Replacer / Reviver
JSON.stringify(obj, (key, value) =>
typeof value === 'bigint' ? value.toString() : value
);
JSON.parse(json, (key, value) =>
key === 'createdAt' ? new Date(value) : value
);
ES バージョン別の追加機能
| バージョン | 追加されたもの (主なもの) |
| ES2015 (ES6) | Map, Set, Promise, Symbol, WeakMap, WeakSet, class, let/const, アロー関数 |
| ES2016 | Array.includes(), 指数演算子 ** |
| ES2017 | async/await, Object.values/entries, padStart/End |
| ES2018 | Spread/Rest, Promise.finally, 非同期反復 |
| ES2019 | Array.flat/flatMap, Object.fromEntries, optional catch |
| ES2020 | BigInt, Promise.allSettled, ?? / ?., globalThis |
| ES2021 | String.replaceAll, Promise.any, 数値区切り 1_000_000 |
| ES2022 | Array.at, Object.hasOwn, クラスフィールド, top-level await |
| ES2023 | findLast, toReversed, toSorted, toSpliced, with |
| ES2024 | Object.groupBy, Promise.withResolvers, RegExp /v フラグ |
TC39 プロポーザル (将来追加されるもの)
| 提案 | 段階 | 説明 |
| Temporal | Stage 3 | Date 置換。タイムゾーン安全な日時 API |
| Iterator Helpers | Stage 3 / 一部実装 | イテレータ版 map/filter |
| Records & Tuples | Stage 2 | 不変な値型 (深い等価比較) |
| Pipeline operator (|>) | Stage 2 | 関数合成構文 |
| Pattern Matching | Stage 1 | match 式 |
FAQ
Q: 新しい API はいつから使っていい?
A: Baseline (web.dev/baseline) で「Widely available」になった時期が目安。またはTC39 Stage 4 で確定です。古いブラウザ対応が必要なら Babel / core-js でポリフィル。
Q: Date と Temporal の違いは?
A: Date はタイムゾーンとサマータイムを正しく扱えない歴史的バグ持ち。Temporal は ZonedDateTime / PlainDate などを分けて表現でき、不変オブジェクトとして安全に扱えます。
Q: Map と通常の Object、どっちを使うべき?
A: キーが固定の構造体 → Object。動的に増減するキー (キャッシュ / カウンタ等) → Map。Map の方が反復・サイズ取得が高速です。