前の記事で無理やりクラス変数を定義する方法を紹介しました。
そんなことをしなくても同様のことはstaticなgetter/setterでできます。
staticなメソッドの記事を書きながら何でこんなことを頑張ったのか orz
単なるstaticなgetter/setterの例です。
class Hoge(){
static set property1(val){
this.prop1 = val;
}
static get property1(){
return this.prop1;
}
}
staticなメソッドの記事でも出てきました。
staticメソッドの中のthis.変数のthisはクラスを指すのでこれはクラス変数として機能します。
前の記事で一番やりたかったことはクラスを定義した時点で動的にクラス変数の値を設定するということです。
これはstaticなsetterでもできます(当たり前orz)。
<div id="HogeTarget">ホゲホゲ</div>
<script>
class Hoge {
static set testStr(val){
this.test_str = val;
}
static get testStr(){
return this.test_str;
}
get testStr(){
return Hoge.testStr;
}
}
Hoge.testStr = document.getElementById("HogeTarget").textContent.trim();
document.write(`Hoge.testStr: ${Hoge.testStr}<br>`);
const a = new Hoge();
document.write(`a.testStr: ${a.testStr}<br>`);
</script>
実行結果以下です。
きちんとクラス変数として使えています。
クラス定義の後、インスタンスをnewする前にクラスのプロパティをセットしてやればstatic initializer的なことも問題ありません。
それから、何となくきちんと動くんじゃないかとは思っていましたが、staticなメソッドとインスタンスメソッドは同名でも問題ないですね。きちんと別物として扱われています。
しかし、行儀が悪いとしてもJavaScript的に問題がないなら前の記事の様にやったほうが楽じゃないか? という意見があるかもしれません。
前の記事では重要な点を妥協しています。
それが、クラス構築時に値をセットしたらそれ以降は変更できないという機能を実現することです。
クラスのプロパティを使うとこれは簡単に実現できます。
<div id="FugaTarget">ふがふが</div>
<script>
class Fuga {
static set testStr(val){
if(!this.test_str){this.test_str = val;}
}
static get testStr(){
return this.test_str;
}
get testStr(){
return Fuga.testStr;
}
}
Fuga.testStr = document.getElementById("FugaTarget").textContent.trim();
document.write(`Fuga.testStr (before reset): ${Fuga.testStr}<br>`);
Fuga.testStr = "Other String";
document.write(`Fuga.testStr (after reset): ${Fuga.testStr}
`);
const b = new Fuga();
document.write(`b.testStr: ${b.testStr}<br>`);
</script>
実行結果です。
setterで「if(!this.test_str){this.test_str = val;}」とすることで、1回値が設定されたら二度と変更できない様にしています。
実行結果からもきちんと機能していることが確認できます。
前の記事の様な行儀の悪いことはせず、staticなgetter/setterを使いましょう。