「JavaScript/クラス」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
268 行
new クラス式の値([引数1[,引数2[..., 引数n]]])
</syntaxhighlight><!-- call や apply の 構文糖 -->
 
=== アクセサプロパティ ===
クラスを導入した動機の1つがカプセル化でしたが、そのクラスのインスタンスのプロパティにダイレクトにアクセスしたのでは本末転倒です(クラスの内部構造が変わったら、プロパティを参照するコードを全て変更するはめになります)。
そこでプロパティアクセス(obj.propやobj[propString]によるアクセス)をオーバーライドする、アクセサプロパティが役に立ちます。
アクセサプロパティは、実際には存在しないプロパティが存在しているかのように見せる仕掛けです<ref>[https://tc39.es/ecma262/#sec-method-definitions ECMA-262::15.4 Method Definitions]</ref>。
{{See also|JavaScript/オブジェクト#アクセサプロパティ}}
 
[[#ES6 の class を使ったコードと相当するES5のコード]]のES6の例を題材にアクセサプロパティを定義してみます。
;アクセサプロパティの使用例:<syntaxhighlight lang="javascript" highlight="3,5-8" line>
class Complex {
constructor(real = 0, imag = 0) {
this.ary = new Float64Array([real, imag])
}
get real() { return this.ary[0] }
set real(n) { return this.ary[0] = n }
get imag() { return this.ary[1] }
set imag(n) { return this.ary[1] = n }
toString() { return `${this.real}+${this.imag}i` }
cadd(n) { return new Complex(this.real + n.real, this.imag + n.imag) }
csub(n) { return new Complex(this.real - n.real, this.imag - n.imag) }
}
let a = new Complex(1, 1)
let b = new Complex(2, 3)
console.info(`a = ${a}
b = ${b}
a.cadd(b) = ${a.cadd(b)}
a.csub(b) = ${a.csub(b)}`)
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
a = 1+1i
b = 2+3i
a.cadd(b) = 3+4i
a.csub(b) = -1+-2i
</syntaxhighlight>
:;内部構造の変更:<syntaxhighlight lang="javascript" highlight="3,5-8" line>
class Complex {
constructor(real = 0, imag = 0) {
this.ary = new Float64Array([real, imag])
</syntaxhighlight>
::real, imagのむき出しのプロパティから2要素のFloat64Arrayに変更
:;アクセサプロパティ:<syntaxhighlight lang="javascript" start=5 line>
get real() { return this.ary[0] }
set real(n) { return this.ary[0] = n }
get imag() { return this.ary[1] }
set imag(n) { return this.ary[1] = n }
</syntaxhighlight>
::real, imagを擬似プロパティとして、それぞれのセッターとゲッターを定義。
::これで、n.real や n.imag で値を参照でき、n.real = 110 のように左辺値化もできます(n.real(), n.imag()や n.real(110) ではないことに注意してください)。
 
=== 脚注 ===