HTML5テクニカルノート
TypeScript入門 05: get/setアクセサをを使う
- ID: FN1609006
- Technique: HTML5 / JavaScript
- Package: TypeScript 2.0.3
get
/set
アクセサを使うと、メソッドをプロパティのように参照して扱えます。読み取り専用プロパティとして定めたり、値の設定時に他のプロパティを処理するなど、単純なプロパティにはできない機能が加えられます。
01 getアクセサを使う
本稿は、「TypeScriptTypeScript入門 04: オブジェクト型リテラルとインタフェースを使う」で書いたコード002「オブジェクト型リテラルとインタフェースを使ったクラス定義」に手を加えてゆきます。このスーパークラス(Point)には、座標の原点からの距離とx座標正方向となす角度を返すメソッド(getLength()とgetAngle())があります。これらをつぎのようにget
アクセサで定めると、それぞれに与えた名前(lengthとangle)でプロパティと同じように参照できるようになります。get
アクセサのメソッドに引数はなく、値を返さなければなりません。
class Point implements IPoint { // getLength(): number { get length(): number { var square: number = this.x * this.x + this.y * this.y; return Math.sqrt(square); } // getAngle(): number { get angle(): number { return Math.atan2(this.y, this.x); } }
get
アクセサは値を返すメソッドとして定め、つぎのようにプロパティのかたちで値が得られます。けれど、設定はできません。つまり、読み取り専用プロパティとして使えます。ただし、設定しても値が変えられないだけで、ビルドでエラーは起こりません。
var obj: Vector = Vector.polar(1, Math.PI / 3); console.log(obj.length, obj.angle * Point.RAD_TO_DEG); // 1 59.99999999999999
距離も角度も、クラス(Point)にはそれにあたるプロパティはなく、座標からそれぞれの値を求めて返しているだけです。get
アクセサが仮想的なプロパティをつくったことになります。
02 setアクセサを使う
set
アクセさを使えば、値ひとつを設定するメソッドがプロパティのかたちで呼び出せるようになります。前掲ふたつのget
アクセサの定めにset
も加えて、読み書きできるプロパティにしてみましょう。クラス(Point)が実際にもっているプロパティは座標(xとy)ですから、距離と角度から座標を求めなければなりません。幸いなことに、そのための静的なメソッド(getPolar())はすでに備わっています。
set
アクセサのメソッドは、つぎのように引数をひとつだけとり、戻り値はありません。距離と角度のうちひとつは引数値に改め、もうひとつはget
アクセサの値を得て、静的メソッドに渡せば新たな座標(point)が求まります。そして、xy座標値をそれぞれのプロパティ(xとy)に定めればよいでしょう。
class Point implements IPoint { set length(length: number) { var point: IPoint = Point.getPolar(length, this.angle); this.x = point.x; this.y = point.y; } set angle(angle: number) { var point: IPoint = Point.getPolar(this.length, angle); this.x = point.x; this.y = point.y; } }
これで、get
/set
アクセサにより、クラス(Point)に読み書きできる距離(length)と角度(angle)がプロパティのかたちで加えられました。つぎのように、値の設定および参照ができます。書き上げたTypeScriptコードは以下にまとめました(コード001)。なお、以下にサンプル001としてCodePenに書いたコードを掲げてあります。
var obj: Vector = Vector.polar(1, Math.PI / 3); obj.length = 2; obj.angle = Math.PI / 6; console.log(obj.length, obj.angle * Point.RAD_TO_DEG); // 2 29.999999999999996
コード001■get/setアクセサを定めたクラス
class Point implements IPoint {
static RAD_TO_DEG: number = 180 / Math.PI;
constructor(public x: number, public y: number) {
}
get length(): number {
var square: number = this.x * this.x + this.y * this.y;
return Math.sqrt(square);
}
set length(length: number) {
var point: IPoint = Point.getPolar(length, this.angle);
this.x = point.x;
this.y = point.y;
}
get angle(): number {
return Math.atan2(this.y, this.x);
}
set angle(angle: number) {
var point: IPoint = Point.getPolar(this.length, angle);
this.x = point.x;
this.y = point.y;
}
static polar(length: number, angle: number): Point {
var point: IPoint = Point.getPolar(length, angle);
return new Point(point.x, point.y);
}
protected static getPolar(length: number, angle: number): IPoint {
var x: number = length * Math.cos(angle);
var y: number = length * Math.sin(angle);
return {x: x, y: y};
}
}
class Vector extends Point {
constructor(x: number, y: number) {
super(x, y);
}
scale(scale): void {
this.x *= scale;
this.y *= scale;
}
add(point: IPoint): void {
this.x += point.x;
this.y += point.y;
}
static polar(length: number, angle: number): Vector {
var point: IPoint = Point.getPolar(length, angle);
return new Vector(point.x, point.y);
}
}
interface IPoint {
x: number;
y: number;
}
サンプル001■TypeScript: get / set accessors
See the Pen TypeScript: get / set accessors by Fumio Nonaka (@FumioNonaka) on CodePen.
- TypeScript: とにかくJavaScriptファイルをビルドしてみる
- TypeScript入門 01: Visual Studio CodeでTypeScriptのコードを書く
- TypeScript入門 02: publicとprivateおよびstatic
- TypeScript入門 03: クラスを継承して使う
- TypeScript入門 04: オブジェクト型リテラルとインタフェースを使う
- TypeScript入門 06: メソッド引数のデフォルト値と省略および定数を定める
- TypeScript入門 07: ブロックスコープに変数を宣言する ー let
- TypeScript入門 08: 型の互換性
- TypeScript入門 09: アロー関数式
- TypeScript入門 10: モジュール ー exportとimport
- TypeScript入門 11: 名前空間 ー namespace
- TypeScript入門 12: デコレータ(Decorator)を使う
作成者: 野中文雄
更新日: 2016年9月23日 TypeScriptのバージョンを2.0.3に更新。
作成日: 2016年9月14日
Copyright © 2001-2017 Fumio Nonaka. All rights reserved.