JavaScript
node-red

Node-redでmsgの中身をコピーするときに値渡しと参照渡しで困った件

node-redもJavascriptなんだからあたりまえなのかもですが、一瞬びっくりしたのでメモ。

状況

  1. CloudantからのID検索により、とあるObject(例えばeventとする)がmsg.payloadに入った
  2. 後々このeventにフラグ一つを追加してCloudantに戻したいので、msg.eventorg = msg.payloadとして他所に逃がしておく。(コピーはFunction NodeでもChange Nodeでも同じ)
  3. その後、msg.payload(msg.eventorgでは無い)の中に入っているカンマ区切りのプロパティをsplitして配列にする。(まぁこの処理は何でもよくて、つまり、payloadを弄るということが言いたい)
  4. その後色々な処理をする
  5. 4の処理が成功したので、以下のようにeventorgで保管していた値に新たなフラグをくっつけて、Cloudantに戻す。
msg.payload = msg.eventorg;
msg.payload.isSent = true;

何が起きるか

3でmsg.payloadに対して処理したsplitが何故かmsg.eventorgにも反映されてしまうのです!オカルト!:scream:

何故か

javascriptの仕様で、オブジェクトのコピー時は参照渡しになってしまうので、後でmsg.payloadを弄ってもmsg.eventorgまで変わってしまうわけです。
オカルトでも何でもないですね。:smile:

ではどうやって回避したか

msg.eventorg = msg.payload

msg.eventorg = JSON.parse(JSON.stringify(msg.payload));
という具合に一度テキストにふやかしてからJSONにすることで、値渡しにすることができます。美しくは無いですが、めでたしめでたし。