オブジェクトを凍結! 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 反応が大好きです。

この著者の最新の記事

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

募集中!(o゜▽゜)o

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

コッチもヨロシク!





最近のネタ!

  1. 2018-10-18

    第9回テーブル部(ボードゲーム)~少人数でまったり~

    2018年8月25日に第9回となるテーブル部活動を開催しました! この日もいつも通り「ボードゲーム…
  2. 2018-10-17

    2018年10月度・第28回 福岡社員総会 & 懇親会

    はじめに 早いものでもうすっかり秋模様ですね🍁 のちほどお伝えする総会&懇親会の様子を見ていただ…
  3. 2018-10-15

    2018年9月度社員総会&懇親会@Tokyo 〜良い表情がいっぱいだね(o゜▽゜)o〜

    遅くなってしまったけれども…… 2018年10月度の社員総会&懇親会@Tokyoが今週末に控えてい…
  4. 2018-10-15

    第7回ボルダリング部 ~いざ! 大根おろしチャレンジ!~

    2018/10/7(土)にボルダリング部の活動がございました! どういう活動内容だったのかご紹介い…
  5. 2018-10-15

    JS で Canvas を操作するときは Konva が結構便利に使えます!

    HTML5 の canvas 使ってますか? こんにちは! 江嵜です。 みなさん、html5 の…
ページ上部へ戻る