技術とかの雑なToday I Learnedメモ

Array.prototype.spliceとArray.prototype.slice、三項演算子のnull coalescing版がほしい話

Array.prototype.splice と Array.prototype.slice のメモ

arr.splice(0)というコードを読んで「???」となったのでメモ。

Chrome の developer tools の console で確認した。

Chrome のバージョン => バージョン: 91.0.4472.114(Official Build) (x86_64)

Array.prototype.splice() - JavaScript | MDN

// splice
// 第一引数: strat (取り除く要素の開始位置)
// 第二引数: deleteCount (startから取り除く要素の数)
// 第三引数以降: item1, item2... (startから追加する要素)

// splice1
// 第三引数を指定しなかった場合は単に指定した位置の要素を削除する
const arr1 = ['a', 'b', 'c', 'd']

const splicedArr1 = arr.splice(0, 1)

// 元の配列を破壊的に変更する
console.log(arr1) //=> ["b", "c", "d"]

console.log(splicedArr1) //=> ["a"]

// splice2
// deleteCountが0だと要素は削除されない
// 第三引数を指定しつつdeleteCountが0だと、startの位置から要素を追加することができる
const arr2 = ['a', 'b', 'c', 'd']

const splicedArr2 = arr.splice(0, 0)

console.log(arr2) //=> ["a", "b", "c", "d"]

console.log(splicedArr2) //=> []

// splice3
// startのみの指定だと、startから配列の終わりまでの全ての要素が削除される
const arr3 = ['a', 'b', 'c', 'd']

const splicedArr3 = arr.splice(0)

console.log(arr3) //=> []

console.log(splicedArr3) //=> ["a", "b", "c", "d"]

なんか似たようなことができる関数あったな〜と思い出したのが slice だったのでこっちもメモっておく。

Array.prototype.slice() - JavaScript | MDN

// slice
// 第一引数: start (取り出す要素の開始位置)
// 第二引数: end (取り出す要素の終了位置)

const arr = ['a', 'b', 'c', 'd']

const slicedArr = arr.slice(0, 1)

const slicedArr2 = arr.slice(0)

const slicedArr3 = arr.slice()

// 元の配列は変更されない
console.log(arr) //=> ["a", "b", "c", "d"]

console.log(slicedArr) //=> ["a"]

// endを省略した場合は配列の最後の要素まで
console.log(slicedArr2) //=> ["a", "b", "c", "d"]

// startもendも省略した場合は配列の最初から最後の要素まで
console.log(slicedArr3) //=> ["a", "b", "c", "d"]

三項演算子の null coalescing 版がほしいという話をしたら反応をもらった

よく if 文の条件分岐とかで条件式を書くときに「0 って false になるっけ」とか「空配列って false になるっけ」とかよく忘れるんですよね。

Falsy (偽値) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN

で、TypeScript3.7 で追加された Optional Chaining と Null Coalescnig の記事を出た当時読んで「なるほど〜」と思ったんですよ。

ここに貼るために当時参考にさせてもらった Qiita の記事を調べたら検索にヒットしないので、もしかしたら消したのかも。

null coalescing は null 合体演算子というやつで、(左辺) ?? (右辺)と書いて、(左辺)が null または undefined だった場合は(右辺)、それ以外は(左辺)を返すというやつ。

コードを書いていると、0 や空配列のときは true だけど null のときは false にしたいみたいな場合が多くあったり、配列がある場合は true でそもそもない場合は false みたいな判定をしたくても、配列の要素数が 0 だと false になっちゃったりしてバグになったりする。

わりと書かれてることだと思うけど、falsy な値での分岐処理はバグを埋め込みやすい。僕も本当にそのとおりだと思う。

で、よく条件分岐として使う三項演算子に null coalescing 版があったらな〜という軽い気持ちでツイートしたのが上記のツイート。

そしたらおもちメタルさん (@omochimetaru) / Twitterがリプライで色々教えてくれた。

よく比較演算子で===とか!==を使うけど、これは比較対象の型も厳密に判定するというやつで、型判定を厳密にすべきだからもちろん==!=より===!==を使うべきだと思って使っていたんだけど、== null!= nullのような nullish な値を判定に使うと、「null もしくは undefined の場合」というのを判定することができる。

これ全然知らなくて、== nullとか!= nullで nullish かどうかを判定できるのを知れたのがとても勉強になった。これを使えば、hoge != null ? fuga : piyoみたいな実質的な三項演算子の null coalescing 版ができる。

ただ、判定機能としては充分だと思うんだけど、「型の厳密さを排除した曖昧な比較が nullish と同等の判定だからうまく使えている」だけの状態な感じもしていて、うまいことハックしている感がある。

なので、やっぱり普通に nullish な判定ができる三項演算子とか if 文とか switch-case 文みたいな記法ができてくれたほうが開発者フレンドリーだなと思った。