フーノページ





JavaScript、
オブジェクトの内容を一時的に変更。

〽️ 最も短い記述で。










JavaScript、サンプルコードの
「これって何?」

〽️ 解らない部分だけ」をピンポイントで解説。

JavaScriptコードの「?」をまとめたページはこちら⬆︎。





syntax。


const obj = {a:"A"};
console.log({...obj,a:"B"});


ベタな書き換え、めんどくさい。


こんにちは、「ふ」です。
今回はオブジェクトの内容を「一時的に」変更する方法について紹介します。

const obj1 = {
    a:"AAA",
    b:"BBB"
};
console.log(obj1);
「「3▶︎ {a:"AAA",b:"BBB"}」」

⬆︎は、オブジェクトの内容を出力する処理です。
普段はこのオブジェクトの内容をそのまま使っているとします。が、例外的にプロパティbの値を"CCC"として使いたいとき。

obj1.b = "CCC";

console.log(obj1);
「「3▶︎ {a:"AAA",b:"CCC"}」」

obj1.b = "BBB";

単純に考えれば⬆︎のように、プロパティにアクセスして値を書き換え→目的の処理→処理が終わったら、またプロパティにアクセスして元の値に戻す。とするでしょう。

しかし....

めんどくさい。

もっと「ササッと」オブジェクトの内容を「一時的に」変更する方法はないものか。
→あります。変更を含んだオブジェクトを複製してしまえばいいんです。




被ったプロパティは上書きされる。


オブジェクトの変更には、"プロパティが上書きされる"というオブジェクトリテラルの性質を使います。

const obj1 = {
    a:"AAA",
    b:"BBB"
};

はじめに作ったオブジェクト「a」は、オブジェクトリテラルによって定義されたものでした。
いま、aの値が「AAA」、bの値が「BBB」となっています。もしここで、もう1度プロパティbを加えるとどうなるのでしょう?
出力して確かめてみましょう。

const obj1 = {
    a:"AAA",
    b:"BBB",
    「「3//同じプロパティ名で追加」」
    b:"CCC"
};

「「3//出力してみる」」
console.log(obj1);
「「3▶︎ {a:"AAA",b:"CCC"}」」

なんと。プロパティbは、あとで記述した"CCC"に値が上書きされています。
プロパティbは2つ記述したのですが、上書きされたものだけがオブジェクトに残されました。
この「上書き作戦」を使えば、内容の書き換え自体はできてしまいます。



複製と変更を同時に。


先ほどの例ではobj1を直接書き換えてしまっているので、従来のものに戻すには再度プロパティの編集が必要になってしまいます。
「元に戻す」作業をしなくてもいいように、変更したものを複製してしまいましょう。

const obj1 = {
    a:"AAA",
    b:"BBB"
};
const obj2 = {};

obj2を作りました。値を波括弧{ }で囲んだ時点で、新規オブジェクトが生成されたことになります。
内部にobj1の内容と、上書きするプロパティを記述します。

const obj2 = {...obj1,b:"CCC"};

obj1の内容記述には、スプレッド構文を使用しました。「...」のあとに続く要素の内容を、一括で記述してくれます。
スプレッド構文については、⬇︎の記事で詳しく解説しています。

JavaScriptの点3つ「 ... 」 〜スプレッド構文(演算子)について。

〽️ 本質は「オブジェクトの複製」にあり。

ではobj1とobj2を出力してみましょう。

console.log(obj1);
「「3▶︎ {a:"AAA",b:"BBB"}」」

console.log(obj2);
「「3▶︎ {a:"AAA",b:"CCC"}」」

元のオブジェクトであるobj1の内容はそのままに、内容を変更したobj2が生成されています。スプレッド演算子を使って、

{...元オブジェクト,変更内容}

とするだけで、一部変更したオブジェクトを使用することができます。また元オブジェクトに影響をあたえることもありません。




引数内で直接作成。


では最終形です。
先ほどは変更複製したオブジェクトをわざわざ定数に代入していましたが、それすら面倒くさい。引数に直接記述してしまいましょう。

const obj1 = {
    a:"AAA",
    b:"BBB"
};
console.log({...obj1,b:"CCC"});
「「3//▶︎ {a:"AAA",b:"CCC"}」」

引数に直接オブジェクトリテラルを記述しました。
「オブジェクト内容を一時的に変更して使う」は、1行だけでできてしまうのでした。




スプレッド構文が最短。


最後までお読みくださり、ありがとうございました。

ところでby the way、「オブジェクトの変更」といえば、Object.assign( )メソッドを使う方法もあります。

const obj1 = {
    a:"AAA",
    b:"BBB"
};

console.log(Object.assign({},obj1,{b:"CCC"}));
「「3▶︎ {a:"AAA",b:"CCC"}」」

Object.asssignメソッドは第1引数にあるオブジェクトに対し、そのあとに続くオブジェクトで上書きしていく、というものです。
第1引数に空のオブジェクト→第2に元オブジェクト→第3に変更内容〜とすれば、今回の処理と同じことができます。が、少しコードが長くなってしまいます。
やはりスプレッド構文が最短で「オブジェクトの一時変更」ができると言えます。



使い回しには注意。

これはスプレッド構文、Object.assignの両方に言えることですが、変更したオブジェクトを使い回す場合には注意が必要です。

const obj2 = {...obj1,b:"CCC"};

記事内の第2段階では、複製したものを定数に格納していました。が、こうして複製したオブジェクトは、内容によっては「参照渡し」になっている場合があります。
もしこの「obj2」に編集を加えた場合、参照渡しの部分が元ネタの「obj1」に影響してしまうおそれがあるのです。この件については対策も含め、またお話しすることにします。

プログラミング学習、楽しく頑張ってください!
ではまた〜 ♪






「ふ」です。

ベクターグラフィック、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。