JavaScript
ECMAScript
プロパティ
オブジェクト
ネスト

JavaScript オブジェクトの深いネストのプロパティを操作する

の二番煎じです。

get/setがあるなら、indeleteにあたるものも作ってみようと思いました。

動作確認はほとんどしていないのでバグがあるかもしれませんが、


  • 基本的に例外を投げない

  • プロパティのキーにはstring型以外にsymbol型も指定できる

  • 返す値は、普通にプロパティを操作するときと同じ

ということを意識しています。


ソースコード

const

getProperty = (object, propertyPath) =>
propertyPath.reduce((object, key) =>
object !== undefined && object !== null && key in Object(object)
? object[key] : undefined
, object),
setProperty = (object, propertyPath, value) =>
(object = getProperty(object, propertyPath.slice(0, -1)))
!== undefined && object !== null
? object[propertyPath[propertyPath.length - 1]] = value
: value,
hasProperty = (object, propertyPath) =>
(object = getProperty(object, propertyPath.slice(0, -1)))
!== undefined && object !== null
&& propertyPath[propertyPath.length - 1] in Object(object),
deleteProperty = (object, propertyPath) =>
(object = getProperty(object, propertyPath.slice(0, -1)))
!== undefined && object !== null
&& propertyPath[propertyPath.length - 1] in Object(object)
? delete object[propertyPath[propertyPath.length - 1]]
: true;


使い方

objectには、プロパティを所得したいオブジェクト(undefinednull以外なら何でも)を指定します。

propertyPathには、プロパティのキーをアクセスする順に並べた配列を指定します。

const object = {

a: {
b: {
'c.d': 'test'
}
}
};
console.log(getProperty(object, ['a', 'b', 'c.d'])); // "test"
console.log(getProperty(object, ['a', 'x', 'y'])); // "undefined"


注意点

このコードをそのまま使おうとはしないでください。前述の通りまともなテストを行っていない上に、代入が式であることや条件(3項)演算子、論理演算子の短絡評価、暗黙の変換などを多用(悪用)しているので、ECMAScriptの仕様をある程度理解している人でないとデバッグも困難です。つまり、バグの温床になり得ます。

逆に、ショートハンドで書こうと思うと、そのような細部の仕様にまで気を遣わなくてはなりません。

最初に挙げた記事の @standard-software さんの意見と若干かぶりますが、コードの簡潔さと質の良さの間に相関関係はありません。ショートコーディングは、趣味の範囲に留めておきましょう。