JSでオブジェクトとか配列が勝手に変更されてしまうのを検出したい!
今日はミーティングメインだったので、ネタがないです。
無理やり絞り出しました。
問題
constとして定義したオブジェクトに勝手にプロパティが追加されている!検出したい。
対策
↓のyosuke_furukawaさんのツイートままですが、Object.freeze()
を開発時のみONにすれば良さそうです。
Object.freezeはconstとして定義したはずのObjectの値を何故か書き換えていたというアプリのバグを見つけた時に、再発防止策として開発中だけfreezeするようにして防ぐという対策を入れました。 http://t.co/PC2IpPlUmk #javascript
— Yosuke Furukawa (@yosuke_furukawa) 2014年12月18日
コード
'use strict'; const obj = {}; const arr = []; if (process.env.NODE_ENV === 'development') { Object.freeze(obj); Object.freeze(arr); } obj.a = 1; // 追加されたところで、例外発生 // arr.push(1); // こちらも追加されたところで、例外発生
実行すると
NODE_ENV=development node a.js
/private/tmp/a.js:11 obj.a = 1; // 追加されたところで、例外発生 ^ TypeError: Can't add property a, object is not extensible at Object.<anonymous> (/private/tmp/a.js:11:7) at Module._compile (module.js:435:26) at Object.Module._extensions..js (module.js:442:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:311:12) at Function.Module.runMain (module.js:467:10) at startup (node.js:134:18) at node.js:961:3 シェルが値を返しました 1
的な。
なお、Object.freeze()は入れ子のオブジェクトには効かないので、その場合は、
を使えばよいかと思います。
まとめ
Node.jsもv0.12以降、Mapがあるので、Objectをデータ保存用途には使わないと思います。
本記事の例はあまり適切ではないかもしれないですが、一応参考程度にということで。