【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にセットするなど応用がきく方法です。
いろいろ試してみてください。
更新日:2021/02/01
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。