JavaScript 黒魔術 - 文字列をキーとしてネストしたプロパティにアクセスする
はじめに
JavaScript の 黒魔術です.
オブジェクトの中にオブジェクトがあってさらにその中にオブジェクトがある. んでその末端のオブジェクトが持つプロパティにサクッとアクセス(get/set)できたら素敵やん!
ってことで, 今回はそれを実現する方法について紹介します.
JavaScript の柔軟性を活かせばこんなこともやれちゃいますよ っていう tips です. 速度的な観点から見ると実用性は微妙なので使用する際にはくれぐれもご注意下さい.
Runstant Demo
とりあえずデモです. 左下のコンソールに実行結果が表示されています.
Object.prototype.$get()
getter です.
define
実装です.
reduce 使って再帰的にオブジェクトを取得して,
最後の値を返しています.
Object.defineProperty(Object.prototype, '$get', {
value: function(key) {
return key.split('.').reduce(function(t, v) {
return t && t[v];
}, this);
},
});
usage
使い方です. こんな感じで使えます.
var obj = {
a: {
b: {
c: '1234',
},
},
};
console.log(obj.$get('a.b.c')); // 1234
console.log(obj.$get('c.b.a')); // undefined
Object.prototype.$set()
setter です.
define
定義です.
$get 同様, 最後の要素になるまで再帰的に オブジェクトを参照しています.
存在しなければオブジェクトを作成します.
Object.defineProperty(Object.prototype, '$set', {
value: function(key, value) {
key.split('.').reduce(function(t, v, i, arr) {
if (i === (arr.length-1)) {
t[v] = value;
}
else {
if (!t[v]) t[v] = {};
return t[v];
}
}, this);
},
});
usage
使い方です. こんな感じで使えます.
var obj = {
a: {
b: {
c: '1234',
},
},
};
obj.$set('a.b.c', '4321');
console.log(obj.$get('a.b.c')); // 4321
obj.$set('c.b.a', 'hoge');
console.log(obj.$get('c.b.a')); // hoge
おわりに
当然, 直接アクセスするのに比べて高負荷ですが, これを使うことでコードがスッキリする場面もあるかと思います.
もしよければ導入してみてください.
ちなみに今回紹介したメソッドは phina.js の実装から抜粋した機能だったりします.
よかったら phina.js も触ってみてください♪
phina.js にはこういった tips が山程あるので, ちょこちょこ紹介していきたいと思います.