自主的20%るぅる

各々が自主的に好き勝手書くゆるふわ会社ブログ

オブジェクトを凍結! JavaScript の seal() と freeze()

今回は 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 書きましょうね!


  1. 「アナと雪の女王」の英語名は「frozen」だそうですよ!シンプル! 
Let’s share this article!

{ 関連記事 }

{ この記事を書いた人 }

アバター画像
takato_ezaki
記事一覧