JavaScriptでネストしたオブジェクトのプロパティへのアクセスを工夫してみる
例えばRubyだとSafe Navigation Operator(&.
)を使えばネストしたプロパティに安全にアクセスできる。
name = product&.retailer&.name
とやれば
retailer
の部分がnilでも例外を吐かずにname
が安全にnilになる。
これをJavaScriptでもやりたいぜ。
もちろん言語レベルではそんなもんなはないので、何にかしらの工夫が必要。
RFCで提唱されている仕様としてはJSON Pointerというやつがあって、これを使えばName Pathからのアクセスが実現できる。
実装としてはnpmにjson-pointerというモジュールが登録されていて、
const { get, set } = require('json-pointer') let product = { /* ... */ } set(product, '/retailer/name', "あいうえお商店") let retailerName = get(product, '/retailer/name') /* ... */
みたいな感じで使える。
あら便利!と思ってしばらく使ってみた。
が。
やっぱめんどくせぇ。。。
Name Pathが直感的じゃないのだ。取得のたびに関数に渡すのも微妙。
もっと良い術がないか。ないな。探した限り。じゃあ作るか。
そして作ったのがこれ ↓↓
Pathを指定してアクセスするのをやめた。代わりShallowな構造とDeepな構造を相互変換できるようにした。
flatten(nested)
で、Nest構造を平たいオブジェクトに変換する。その際、プロパティ名は"."つなぎになる
const { flatten } = require('objnest') let flattened = objnest.flatten({ 'foo': {'bar': 'baz'} }) console.log(flattened) // => {'foo.bar': 'baz'}
逆に構造化したい場合はexpand(flattend)
する。"."つなぎのプロパティがネストされたオブジェクトになる。
const { expand } = require('objnest') let expanded = expand({ 'foo.bar': 'baz' }) console.log(expanded) // => {foo: {bar: 'baz'}}
使って見るとこれがなかなか便利。Reactの高速化の時にShallowCompareで扱えるようにしたりね。ビバ俺様仕様。