6
5

More than 5 years have passed since last update.

JavaScriptでオブジェクトの深い階層に安全にアクセスする

Last updated at Posted at 2017-05-17

はじめに

nullsafe-objectというnpmライブラリを公開したので紹介します(手前味噌かーい)。

概要

オブジェクトの深い階層のプロパティに 自然な形で安全に アクセスする方法を提供するライブラリです。

Example

const NullSafeObject = require('nullsafe-object');
const srcObj = {};

// 空のオブジェクトなので普通に下のようにアクセスすると
// Uncaught TypeError: Cannot read property 'info' of undefined
// とか言いながら死ぬ
// console.log(srcObj.deep.property.access);

// NullSafeObjectで包む
const obj = NullSafeObject.wrap(srcObj);

// 深い階層にアクセスして unwrap() メソッドで結果を取得できる
console.log(obj.deep.property.access.unwrap()); // => null

// 存在するプロパティにももちろんアクセスできる
const srcObj2 = {
    exists: {
        property: 'some string'
    }
};
const obj2 = NullSafeObject.wrap(srcObj2);

// unwrap() メソッドは必須
console.log(obj2.exists.property.unwrap()); // => 'some string'

// githubのREADMEに書くの忘れてたけどちゃんと代入もできる
obj.new_property = 'hoge';
// 元のオブジェクトに反映されている
console.log(srcObj.new_property); // => 'hoge'

インストール方法

いつもの
npm install --save nullsafe-object
yarn add nullsafe-object

実現方法

ES2015で追加されたProxyを使用しています。Proxyについてはこちらの記事が参考になります。あとはMDNとかを見ていただきたいきもち。
対応ブラウザはこのへんを見ると良いと思います。IE11ってなんですか?。
NullSafeObject.wrapは内部でNullSafeObjectのインスタンスを作成しており、作成されたインスタンスをProxyに渡してプロパティアクセスをフックする処理が書いてあるみたいな感じです。
プロパティアクセスをフックすると「どのキーにアクセスしたか」がわかるので、アクセスしたキーを順番に保存していきます。
NullSafeObject#unwrapを呼び出すと、元のオブジェクトから、保存したキーを順番にたどっていき、途中でnullだったりundefinedだったりしたらnullを返すようにしています。
代入もフックできるので、いいかんじにやってます(キーボード打つのにつかれてきた人が書く解説)(そのうち編集しなきゃ)。

なぜ作ろうかと思ったか

ぶっちゃけProxyで何か面白いことできないかなって思ったのが9割くらいですね。
あとは前々から途中にnullやらundefinedがあってしぬみたいなことがあってストレスが溜まってたのが残りの1割(?)
(実は、全然難しい実装ではないのになんで作られていなかったんだろうと心配になっています。知らないだけで類似ライブラリあったのかな・・・)

これから対応したい機能

  • Array#mapとかの呼び出しにも対応したい(できるのか不明)(テストコードだけ書いて対応してないせいでテストがしんでる)
  • obj._root obj._pathとかやると、もとのオブジェクトの_root_pathではなく、クラス内部で使用している管理用オブジェクトに触れることができてしまうのでそれをなんとかしたい(方針は立っていて、Symbolを使えば良さそう) => 対応しました

さいごに

使用感の報告やIssueやプルリクをいただけると泣いて喜びます!

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5