オブジェクトを凍結! 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」だそうですよ!シンプル! 
Takato Ezaki

Takato Ezaki小中高の塾講師からエンジニア

投稿者プロフィール

福岡で Web 系のエンジニアをしています。

中高の理科教師免許を取り、起業に 2 年間トライした後エンジニアの道へ入りました。

化学反応の中では Belousov-Zhabotinsky 反応が大好きです。

この著者の最新の記事

関連記事

コメントは利用できません。

募集中!(o゜▽゜)o

エンジャパン
求む、社長!
follow us in feedly

コッチもヨロシク!





最近のネタ!

  1. 2018-12-15

    エージェントグローで働く30代SEが活用している福利厚生/教育制度の話【Agent Grow Advent Calendar 2018:15日目】

    ご挨拶 この記事はAgent Grow Advent Calendar 2018 15日目の記事で…
  2. 2018-12-14

    ベイビー・トーク・ウィズ・モンキー【Agent Grow Advent Calender 2018:14日目】

    グッド・モーニング この記事はAgent Grow Advent Calendar 2018 14…
  3. 2018-12-13

    第12回テーブル部活動~脱毛ガールズと星空超月爆破~【Agent Grow Advent Calender 2018:13日目】

    この記事は  Agent Grow Advent Calendar 2018  13日目の記事となり…
  4. 2018-12-12

    第1回 倶楽部ぽじてぃぶ ~初活動! ボルダリング~

    名古屋オフィスの社内サークルである「倶楽部ぽじてぃぶ」。 「今後の人生に役立つような頭や身体を刺激…
  5. 2018-12-12

    第二回リアル脱出ゲーム部~謎の部屋からの脱出 in 下北沢~【Agent Grow Advent Calendar 2018:12日目】

    はじめに この記事はAgent Grow Advent Calendar 2018 12日目の記事…
ページ上部へ戻る