今回は JavaScript でのオブジェクトの凍結について
こんにちは!江嵜です!
皆さん今日も JavaScript 書いてますか?
今回はあまり日の当たらないところですが、知っておくと役に立つ(かもしれない)オブジェクトの凍結についてお話します!
オブジェクトの凍結とは…?
オブジェクトの凍結とは何でしょうか?
凍結とは、一言で言えば「変更できないようにする」ということですね。
いわゆる変数に対する定数と呼ばれるヤツですね!
Java なんかだと final
という修飾子をつけることで実現ができます。
実は JavaScript にも ES6 (最近の仕様)からは変数定義の際に const
というものを使用することができまして、
const foo = '文字を入れるよ'; foo = '変更する';
みたいにすると、 foo
は定数として定義できますので 2 行目の再代入でエラーを発生させることができます。
こういった仕組みがあることで、プログラム内で好きに変更してほしくない値(DB への接続情報とか、ありますよね!)を
保護することが出来る、ということなんですね。
ではオブジェクトではどうする?
ではオブジェクトではどうでしょうか、
次のようにオブジェクトリテラルを用意して試してみると
const foo = {hoge: 'test'}; foo = {hoge: 'changed'};
これはエラーになります。
がしかし…
const foo = {hoge: 'test'}; foo.hoge = 'changed!'; foo.fuga = 'fuga' console.log(foo);
これだとどうでしょうか。結果はこちら。
[object Object] { fuga: "fuga", hoge: "changed!" }
見事に foo.hoge
の値は書き換えられ、新しい fuga
という値も追加されてしまいました。
(実際に皆さんも試してみてくださいね。)
じつは、 const
では再代入は防げますが、オブジェクトの中身までは保護できないのですね。
オブジェクトの中身も丸っと保護する方法はないのでしょうか…?
seal で保護してみる
実はオブジェクトの中身を保護する方法があります。
それがこちら。
Object.seal(foo);
Object.seal()
にオブジェクトを渡してあげることで、そのオブジェクトを保護することができるのです。
試しに先程のコードを実施してみると…
const foo = {hoge: 'test'}; Object.seal(foo); foo.hoge = 'changed!'; foo.fuga = 'fuga' console.log(foo);
[object Object] { hoge: "changed!" }
foo.fuga
の追加を抑止できましたね!
ちなみに、通常ではこのようにただ無視されるだけなのですが、
JavaScript ファイルの先頭に "use strict";
と書いて厳格モードにすればきちんとエラーが出るようになります。
ただ、これだけではちょっとまだ心もとないですね。
Object.seal()
はオブジェクトへのプロパティの追加・削除を抑止できますが、変更は止められないのです。
これはこれで便利ですが、すべての変更を抑止したい!という事もありますよね。
そんな時はどうするのでしょうか?
freeze で凍結!
そんなときの為に Object.seal()
よりもさらに強いものがあります!
それが Object.freeze()
です。
雪だるまつくろー⛄ ドアを開けてー♪ 1
なんとなく予想はついているかと思いますが、試してみましょう。
const foo = {hoge: 'test'}; Object.freeze(foo); foo.hoge = 'changed!'; foo.fuga = 'fuga' console.log(foo);
結果はこちら
[object Object] { hoge: "test" }
確かにすべての変更を無視していますね!
こちらも普通に使うだけですと変更を無視するだけですが、厳格モードにすればきちんとエラーが出てくれます。
これでオブジェクトの保護もバッチリですね!
これで安全に JavaScript を書きましょう!
ちなみに、同じ系列で Object.preventExtensions()
という追加のみを抑制する(変更や削除は許可)というものがありますが、
大体 Object.seal()
で事足りるかなと思います。
柔軟性が高いのが JavaScript の良さではありますが、
きっちり守るところは守って、安全に JavaScript 書きましょうね!
- 「アナと雪の女王」の英語名は「frozen」だそうですよ!シンプル! ↩