お知らせ:2021/2/18 ツールサイト(affi-sapo-sv.com)から、開発ノートを独立させました。
【JavaScript】 thisは上書き不可なのにプロパティ追加できる理由
更新日:2021/02/01
ツイートthisは読み込み専用のため、上書きできません。
しかしプロパティ追加はできます。
『上書きでないのに、追加できるってどういうこと???』
と思った方は、読んでください。
検証してみる
thisのプロパティ操作は、コンストラクター関数でおこなうことが多いです。
そこで、コンストラクター関数でthisの上書き検証をおこなってみます。
function getObj(){ this.prop1 = 100; // (a) this.prop2 = 200; // (a) this = { // (b) Uncaught SyntaxError: invalid assignment left-hand side prop1:100 prop2:200 }; } const o = new getObj();
上のコードの (a)は、thisに新規プロパティを追加して、数値で初期化しています。
このコードは、問題なく実行できます。
次の(b)は、プロパティを定義したオブジェクトをthisにセットしています。
するとエラーがスローされてしまいました。
thisに複数のプロパティを追加する場合、(a)のように一つ一つ書いていくのは美しくありません。
またオブジェクトを使えないとなると、ゲッターとセッターを定義したい場合Object.definePropertyメソッドを使用する必要があります。
Object.defineProperty(this,プロパティ名,{ get:()=>変数名 });
(b)のオブジェクトを使えれば、とても楽なんです。
不可能なんでしょうか?
読み込み専用のため、上書きないとは?
thisが読み込み専用のため上書きできないという意味を、次の図で解説してみます。
thisだけでなくて変数やプロパティも同様なのですが、割り当てられている値は実体ではありません。
割り当てられているのは、実体に割り振られた識別ラベルのようなものです。
読み込み専用や上書き禁止とは、このラベルを他のラベルに置き換えることができなという意味です。
一方、オブジェクトの実体は特に制約を受けていません。
そのため自由に、プロパティの追加やプロパティ値の変更を行えるのです。
Object.freezeメソッドを使用すると、オブジェクトの実体にプロパティ追加を禁止させることができます。
thisに一括でプロパティ追加したい
thisにオブジェクトを直接代入するのは、不可能だということがわかりました。
しかしそれでも『this.プロパティ名 = 値』の羅列は回避したいですね。
そこで別途オブジェクトを用意しておいて、最後にthisにセットする方法があります。
function getObj(){ let val = 100; const obj = { prop1:100, prop2:200, get val(){ return val; } }; Object.keys( obj ).forEach( e => this[ e ] = obj[e] ); }
変数のカプセル化をオブジェクトを関連する変数ごとに分けて、最後にまとめてthisにセットするなど応用がきく方法です。
いろいろ試してみてください。
記事の内容について

説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
ご意見はこちら。
https://note.affi-sapo-sv.com/info.php
【お願い】

■このページのURL
■このページのタイトル
■リンクタグ