Array.prototype.with の命名について
tc39/proposal-change-array-by-copy
tc39/proposal-change-array-by-copy
は TC39 に提案されている 2022-12-27 現在で Stage3 の proposal です。
本 proposal では、配列に対して破壊的な変更を行うメソッドに対して同様の処理を非破壊的に行えるメソッドを追加することが提案されています。
Array.prototype.toReversed() -> Array
Array.prototype.toSorted(compareFn) -> Array
Array.prototype.toSpliced(start, deleteCount, ...items) -> Array
Array.prototype.with(index, value) -> Array
Array.prototype.with
って?
toReversed
, toSorted
, toSpliced
は名前から挙動の推測がつきますが、 with
だけはわかりませんでした。
proposal 内の Example には Array.prototype.with
が以下のような挙動をするようです。
const correctionNeeded = [1, 1, 3];
correctionNeeded.with(1, 2); // => [1, 2, 3]
correctionNeeded; // => [1, 1, 3]
Spec も合わせて読むと、挙動は以下のようなものになりそうです。
-
arr.with(index, value)
はarr
のうち、index
番目をvalue
に置き換えたものをarr
を破壊することなく生成する - 第一引数には
Array.prototype.at
と同様にArray
の index を相対的に指定できる- 例:
-1
を指定するとArray
の末尾を置き換え位置の対象にできる
- 例:
Chrome 108 から Developer Trial が開始しているため、 enable-javascript-harmony
を有効化することで動かすことができます。
(chrome://flags/#enable-javascript-harmony
から有効化できます。)
Array.prototype.with
という命名なのか?
なぜ 他の命名もあったはずですが、なぜ with
という抽象度が高い命名になったのかが気になったので調査しました。
proposal の issue を漁ってみると丁度ドンピシャな質問をしている issue がありました。
why
with()
and not something likereplaceValue()
?
Some of the reasons for choosing with were brevity and also because of the similarities to its use in the Temporal proposal.
ということで「Temporal.PlainDate.prototype.with
と似ているから」が理由らしいです。
Temporal.PlainDate.prototype.with
の命名理由も調べてみる
Temporal.PlainDate.prototype.with
が spec に追加されたのはこの commit からのようですが、命名については議論されてなさそうでした。
おそらく Temporal.PlainDate.prototype.with
は Temporal.PlainDate.prototype.withCalendar
をより汎用化する過程で Calendar
を取ってできた命名だったのではないでしょうか。
(with
という単語が検索難易度を格段に引き上げているため調査が大変でした...)
Array.prototype.pushed
はどこいった?
おまけ: Stage 2 の途中までは Array.prototype.push
を非破壊的に行う Array.prototype.pushed
などがあったはずですが、気がついたら以下の議論の末に消えてました。
Discussion