Edited at

JavaScript オブジェクトの深くネストされているプロパティに値をセットする setProperty

前の記事で、getProperty を作りました。

JavaScript オブジェクトの深くネストされているプロパティに安全にアクセスする getProperty - Qiita

https://qiita.com/standard-software/items/bb044217d0a4b394b8e2

今回は、オブジェクトの深くネストされているプロパティに値をセットする setProperty を作ってみました。

JSでは、値の全書き換えのときに深いネストのプロパティ値を書くのは、そんなに面倒でもなんでもないです。(括弧の対応は少し面倒かも)

ですが、そのオブジェクトの一部の値だけ上書きしたいとか、そのときにその深いネストのところのプロパティが存在したりしなかったり不定とかいう場合に、この setProperty は便利になるでしょう。


ソースコード

function isObject (item) {

return typeof item === 'object'
&& item !== null && !Array.isArray(item);
}

function setProperty(object, path, value) {
if (!isObject(object)) { return; }

const propertyArray = path.split('.');
for (let i = 0; i <= propertyArray.length - 1; i += 1) {
if (propertyArray[i] === '' ) { throw new Error('setProperty path'); }
}

let result = object;
for (let i = 0; i <= propertyArray.length - 2; i += 1) {
if (!isObject(result[propertyArray[i]])) {
result[propertyArray[i]] = {};
}
result = result[propertyArray[i]];
}
result[propertyArray[propertyArray.length - 1]] = value;
}

let testObj1 = {
}
var path = 'a.b'; setProperty(testObj1, path, true); console.log(path, testObj1);
var path = 'a'; setProperty(testObj1, path, true); console.log(path, testObj1);
var path = 'a.b.c'; setProperty(testObj1, path, true); console.log(path, testObj1);
// var path = ''; setProperty(testObj1, path, true); console.log(path, testObj1);
// var path = 'a.'; setProperty(testObj1, path, true); console.log(path, testObj1);
// var path = '.a'; setProperty(testObj1, path, true); console.log(path, testObj1);
var path = 'a.c'; setProperty(testObj1, path, true); console.log(path, testObj1);
var path = 'b'; setProperty(testObj1, path, true); console.log(path, testObj1);
var path = 'b.c'; setProperty(testObj1, path, true); console.log(path, testObj1);

動作確認部分でコメントアウトしているものは例外発生します。プロパティのパスをピリオドで分解したときに空文字が入っているものがあるからです。

もしかしたらプロパティ名に使えない記号文字が入っていたら、なんらかのエラーが出てしまうかもです。もしご存知でしたら教えてください。

そういうパターンも網羅しておいて、プロパティパス部分にこういう文字列を記載すると例外が発生するよ。ということを明示的にテストコードを書くとソースコードの品質があがりますね。

例外が発生するか発生しないかのテストの書き方は次の記事で書いてあるので、ご参考にしてください。

有名なテストフレームワークには多分例外補足テストの処理が搭載されているとは思いますが、大掛かりなものではなくてもソースコピペで十分に例外処理可能なテストフレームワークを作ることもできます。

JavaScriptで世界一簡単なテストフレームワークに例外捕捉機能追加した - Qiita

https://qiita.com/standard-software/items/d4fb99655e17a3a68fcb