Kyoto.なんか #6 で発表しました.
以下はその補足情報など.
仕様書中の出現頻度
null と undefined がそれぞれの仕様でどの程度使われているのかは, 仕様書中の出現頻度を見るだけでもある程度わかりりそうです. ということで ECMAScript 2024 と WHATWG の標準 (2024-09-07 時点) のうちいくつかの仕様書の中での出現頻度を見てみましょう.
Spec | #null | #undefined |
---|---|---|
ES2024 | 300 | 939 |
DOM | 368 | 120 |
Fetch | 276 | 10 |
HTML | 1778 | 275 |
URL | 98 | 9 |
見ての通り, 顕著に登場頻度に差があることがわかりますね.
なお上記の null の出現数には WebIDL の nullable (T?
) を含めていないため, Web 標準における実際の null の登場頻度はもっと多くなるはずです.
仕様書の null 全部読む
上記の通り ES2024 の仕様には null が 300 回しか登場しません. この程度なら null の登場箇所は全部読めるなと思ったので読みました.
いくつか手元のメモから面白かった箇所を抜粋します:
- null がオブジェクトの prototype となるのは, プログラマがそうした場合を除くとたぶん以下のいずれか
Object.prototype
- import されたモジュール (
import * as foo from "..."
としたときのfoo
) Object.groupBy
で作られるオブジェクトRegExp.prototype.exec
が返すgroups
オブジェクト- named capturing group を使うと登場する
Array.prototype[@@unscopables]
が返すオブジェクト- あの
with
で使われるらしい
- あの
Date.prototype.toJSON
は時刻が finite でないとき null を返すString.prototype.matchAll
が返すイテレータは null を返す的なことが書いてあるが, たぶん普通はそんなことはないArray.prototype.join
は配列中の null や undefined を無視するObject.assign
は引数中の null や undefined を無視するMap
,Set
,WeakMap
,WeakSet
のコンストラクタは引数に null や undefined が渡されると無視する
ECMAScript の言語仕様での例外的なケースについて
スライド中でも紹介した通り, ECMAScript の言語仕様中で null が使われるのは (仕様内部での利用を除けば) 以下の 3 つです.
このうち JSON で null が使われる理由は明白で, JSON の仕様でそう定義されているためです.
正規表現についてはおそらく歴史的な事情で, 今となっては特に深い意味はないものと思われます. (この理由に関する情報を昔見かけたことがある気もしますが, 真偽が定かでないのでここで広めるのはやめておきます.)
プロトタイプについては, ES5 より前には仕様内部で用いられていたものが, ES5 以降に Object.getPrototypeOf
などが追加されたことで正式に表に出てくるようになったものと考えています.
Web 標準仕様で例外的なケースについて
例えば CustomElementRegistry#get
が custom element が見つからない時に undefined を返すようです.
オブジェクトや文字列に対しては null を使うのでは?
文字列は JavaScript ではプリミティブ値の一種ですが, 他の言語ではオブジェクト側に分類されることもあります. 実際, ECMAScript の言語仕様における例外ケースや Web 標準の慣例は, こういった他の言語の仕様や慣習に由来するものでほぼ間違いないでしょう.
一方, その他のプリミティブ値に対してであったり, プリミティブ値とオブジェクトが混在する場合に null と undefined のどちらを使うのかは, これだけでは説明できないはずです. ECMAScript の言語仕様でもこういった場合に null を使っても良いはずですが, 原則 undefined を使うように統一されています.
また TypeScript を使う場合に Map<string, string>
と型を制限したからといって get()
したときに null が返るかというとそんなことはないので, やはり出自も考えるほうが混乱しないでしょう.