2025年11月にObject.keysLengthというproposalが提出されました。
ステージの進行に年単位の時間がかかることも珍しくないTC39において、提出された瞬間ステージ2のステータスになっていました。
そんなにみんなが欲しがる機能なのでしょうか。
いったいどんな便利機能なのか、proposalを見てみましょう。
Proposal: Object.keysLength
Overview
Object.keysLength(target)は、文字列キーを持つ列挙可能なプロパティの数を返します。
これはObject.keys(target).lengthと全く同じですが、中間変数を使用しません。
Object.keysLength(obj) === Object.keys(obj).length;
Motivation
開発者は、文字列キーを持つ列挙可能なプロパティの数を調べるためにObject.keys(obj).lengthという記述を頻繁に行います。
一見わかりやすいですが、JavaScriptエンジンは関数が呼ばれるたびに配列を作成するため、本来は不要であるメモリ割り当てとGCのオーバーヘッドが発生します。
このコストは、チェックを何度も繰り返すフレームワークやライブラリでは大きな負荷になる可能性があります。
このproposalでは、中間配列を作成せずに同じ情報を返す組み込み関数を提供します。
・不要な割り当てとGCを避ける
・コードの意図が明確
・JavaScriptエンジンによる直接の最適化を可能にする
このproposalは、列挙可能な文字列キーを持つプロパティに限定して取り組んでいます。
より広範な、列挙不可能なプロパティやシンボルなどについては、親提案であるObject.propertyCountでカバーされます。
Proposed API
Object.keysLength(target)
・引数targetにnull・undefinedを渡すとTypeErrorが発生する。
・返り値は非負整数で、Object.keys(target).lengthと同じ。
正確な仕様はspecを参照してください。
Examples
基本的な使い方。
Object.keysLength({}); // 0
Object.keysLength({ a: 1, b: 2 }); // 2
Object.keysLength(/./.exec('a')); // 4 ('0', 'index', 'input', 'groups')
プロトタイプのないオブジェクト。
const o = { __proto__: null };
o.x = 1;
Object.keysLength(o); // 1
疎配列。
Object.keysLength([, , 3]); // 1 空はカウントされない
const a = [];
a[10] = 'x';
Object.keysLength(a); // 1
シンボルはカウントされない。
const s = Symbol('s');
const obj = { a: 1, [s]: 2 };
Object.keysLength(obj); // 1
列挙できないプロパティはカウントされない。
const obj = { a: 1 };
Object.defineProperty(obj, 'hidden', { value: true, enumerable: false });
Object.keysLength(obj); // 1
Object.keysLength([]); // 0
プリミティブ型はObject.keys同様に型変換される。
Object.keysLength('abc'); // 3 [a,b,c]になる
Object.keysLength(42); // 0 []になる
エラー。
Object.keysLength(null); // TypeError
Object.keysLength(undefined); // TypeError
Relationship to Object.propertyCount
Object.keysLengthは、より大規模なObject.propertyCountの焦点を絞ったサブセットです。
Object.keysLengthは、Object.keysと一致するようにセマンティクスが固定されています。
Object.propertyCountでは、オプションでシンボルや列挙できないプロパティもカウントできる柔軟なAPIが検討されています。
Prior art and usage
Object.keys(obj).lengthパターンは、React・Angular・Vue・Lodash・Node.js・Storybook・VS Codeといった様々なフレームワークやライブラリで頻出しています。
このAPIでは、セマンティクスを変えることなく、このコードを高速化することができます。
感想
これいる?
単体で見れば微妙な感じもしますが、しかしこのproposalの実体は、規模が大きいせいでステージが進まないObject.propertyCountのproposalから一部を切り出したものです。
あえて規模を小さくすることでフットワークを軽くし、スピーディに進めることができたというわけです。
単機能すぎるのも想定内ということですね。
しかしObject.propertyCountの提案を軽く見てみたところ、中身はObject.getOwnPropertyNamesLength(obj)・Object.getOwnPropertySymbolsLength(obj)という単なるふたつのメソッドを追加するだけの提案になっており、オプションを渡す余地はありませんでした。
なんかこちらのproposalと言ってることが違うな?
どうも当初の案では数えるキーの型を限定したり、列挙できないプロパティだけを数えたりといったオプションを使える予定だったみたいです。
しかしその後何故かそのあたりがなくなってオプションを渡せない関数だけになったので、説明に矛盾が生じてしまったようです。
担当者は同じなのだから、そういったのは修正してほしいところですね。