JavaScript | ES6+ 文法:新データ構造 – size プロパティ

JavaScript JavaScript
スポンサーリンク

size プロパティとは何か(まずイメージから)

size プロパティは、
「そのコレクションの中に、今いくつ要素が入っているか」を教えてくれる数字 です。

ES6 の新しいデータ構造では、

  • Map
  • Set

size が用意されています。

const s = new Set([1, 2, 3]);
console.log(s.size); // 3

const m = new Map([
  ["a", 1],
  ["b", 2],
]);
console.log(m.size); // 2
JavaScript

ここが重要です。
size は配列の length と同じような役割を、MapSet に対して担っている と考えるとイメージしやすいです。

Object.length との違い(ここで一気にスッキリさせる)

Object には length / size がない

配列には length がありますが、
普通のオブジェクト {} には、「プロパティがいくつあるか」を直接教えてくれるプロパティはありません。

const obj = { a: 1, b: 2, c: 3 };

console.log(obj.length); // undefined
// console.log(obj.size); も undefined
JavaScript

オブジェクトの「プロパティ数」を知るためには、
少し遠回りが必要です。

const count = Object.keys(obj).length;
console.log(count); // 3
JavaScript

Map / Set では size が一発で取れる

MapSet は、「コレクションの大きさ」をよく使うことを前提に設計されています。

const set = new Set();
set.add("a");
set.add("b");

console.log(set.size); // 2

const map = new Map();
map.set("x", 10);
map.set("y", 20);
map.set("z", 30);

console.log(map.size); // 3
JavaScript

ここが重要です。
「要素数を頻繁に知りたいコレクション」なら、Object より Map / Set を使ったほうが素直 です。
Object.keys(obj).length を毎回書く必要がありません。

Set と size の具体例

登録済みユーザー数を数える

const users = new Set();

users.add("alice");
users.add("bob");
users.add("alice"); // 重複なので無視される

console.log(users.size); // 2
JavaScript

Set は「重複しない集合」なので、
size は「ユニークな要素がいくつあるか」を表します。

条件を満たした要素を集めて size を見る

例えば、「偶数だけ集めて、その数を知りたい」場合。

const nums = [1, 2, 2, 3, 4, 4, 4];

const evenSet = new Set();

for (const n of nums) {
  if (n % 2 === 0) {
    evenSet.add(n);
  }
}

console.log(evenSet);      // Set(2) { 2, 4 }
console.log(evenSet.size); // 2(偶数の種類が 2 種類)
JavaScript

配列でやろうとすると、「重複を避けて、さらに長さを数える」という二重の作業になりますが、
Set + size なら、かなりシンプルに書けます。

Map と size の具体例

キャッシュの中身が「今いくつあるか」を知る

const cache = new Map();

cache.set("user:1", { name: "Alice" });
cache.set("user:2", { name: "Bob" });

console.log(cache.size); // 2

cache.delete("user:1");
console.log(cache.size); // 1
JavaScript

Map は「キー → 値」のペアを持つ辞書でした。
size は、そのペアが何件あるかを教えてくれます。

ログイン中ユーザー数を数える(ID → ユーザー情報)

const loggedInUsers = new Map();

// ログイン
loggedInUsers.set(1, { id: 1, name: "Alice" });
loggedInUsers.set(2, { id: 2, name: "Bob" });

console.log("ログイン中:", loggedInUsers.size); // 2

// ログアウト
loggedInUsers.delete(1);

console.log("ログイン中:", loggedInUsers.size); // 1
JavaScript

ここが重要です。
Map / Set の size は、「状態」をそのまま数字で確認する感覚 と相性がいいです。
「今何件キャッシュされている?」「今何人ログインしている?」といった問いに、map.size / set.size で直接答えられます。

size は読み取り専用(自分で書き換えない)

size に代入しても意味はない

size読み取り専用 のプロパティです。
自分で変更するものではありません。

const set = new Set([1, 2, 3]);

console.log(set.size); // 3

set.size = 100;        // 無視される(エラーにならない環境も多い)

console.log(set.size); // 3 のまま
JavaScript

要素を増やしたいなら add / set
減らしたいなら delete / clear を使います。

set.add(4);      // size が 4 になる
set.delete(2);   // size が 3 に戻る
set.clear();     // size が 0 になる
JavaScript

ここが重要です。
size は「結果」であって、「原因」ではない
「中身を変える」→「size が変わる」という順番で、逆ではありません。

WeakMap / WeakSet には size が「ない」

なぜ Weak 系には size がないのか

WeakMapWeakSet は、
ガベージコレクション(メモリからの自動解放)と連動しているため、
「中に何個入っているか」をユーザーが信頼できる形で提供できません。

そのため、

const wm = new WeakMap();
const ws = new WeakSet();

console.log(wm.size); // undefined
console.log(ws.size); // undefined
JavaScript

size プロパティ自体がありません。

「今いくつあるか」「全部で何が入っているか」を知りたい構造ではない、
という設計になっています。

ここが重要です。
「size を使いたい」「個数を数えたい」と思ったら、Weak ではなく普通の Map / Set を使うべき という判断軸になります。

実務での size の使いどころ

「空かどうか」のチェックにとても便利

Map / Set が空かどうかを確認するのに、size は直感的です。

if (set.size === 0) {
  console.log("Set は空です");
}

if (map.size > 0) {
  console.log("何か入っています");
}
JavaScript

Object で同じことをすると、こうなります。

if (Object.keys(obj).length === 0) {
  console.log("空っぽのオブジェクト");
}
JavaScript

この違い、地味ですが、毎日のコードでじわじわ効いてきます。

上限チェック(例:キャッシュやキューの制御)

「最大 100 件までキャッシュする」といった上限を設ける場合にも、size が活躍します。

const cache = new Map();
const MAX_CACHE_SIZE = 100;

function setCache(key, value) {
  if (cache.size >= MAX_CACHE_SIZE) {
    console.warn("キャッシュが満杯です");
    return;
  }
  cache.set(key, value);
}
JavaScript

size を見るだけで、「これ以上入れていいか」を判断できます。

まとめ

ES6 の新データ構造における size プロパティのポイントを整理します。

MapSet には size があり、「今入っている要素数」を一発で取得できる
Object には size / length がないので、Object.keys(obj).length のような回り道が必要
size は読み取り専用で、自分で書き換えるものではない(中身の増減で自動的に変わる)
WeakMap / WeakSet には size が存在しない(中身の個数を扱う用途では使わない前提)
「空かどうか」「上限を超えていないか」をチェックするのに、size はとても便利

まずは、辞書や集合っぽく使っているオブジェクトがあったら、
それを Map / Set に置き換えてみて、

if (map.size === 0) { … }
if (set.size > 10) { … }
JavaScript

のような書き方を 1 か所でも体験してみてください。

「Object.keys(…).length」と比べたときのスッキリ感が、
Map / Setsize を使うモチベーションを、自然に押し上げてくれます。

タイトルとURLをコピーしました