サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

TypeScript入門 06: メソッド引数のデフォルト値と省略および定数を定める


TypeScriptでは、メソッドの引数にデフォルト値を与えたり、引数を省略することもできます。また、値の変えられない定数の定め方についてもご説明します。

01 メソッドの引数にデフォルト値を与える

本稿は、「TypeScript入門 05: get/setアクセサをを使う」で書いたコード001「get/setアクセサを定めたクラス」に手を加えてゆきます。このスーパークラス(Point)のコンストラクタには、座標値をふたつの引数として与えます。引数を渡さずに呼び出せば、引数の数が合わないというつぎのようなエラーが示されます。

Supplied parameters do not match any signature of call target.

けれど、引数なしに呼び出したとき、たとえばデフォルト値として0を与えることができると便利です。メソッドや関数の引数には、つぎのように=演算子でデフォルト値が定められます。引数を受け取ればその値、引数がないときはデフォルト値が使われることになります。サブクラス(Vector)のコンストラクタもスーパークラス(Point)と同じ引数をとりますので、デフォルト値を加えました。


class Point implements IPoint {

	constructor(public x: number = 0, public y: number = 0) {
	}

}
class Vector extends Point {
	constructor(x: number = 0, y: number = 0) {
		super(x, y);
	}

}

これで、コンストラクタを引数なしに呼び出したときは、つぎのようにデフォルト値がプロパティに与えられます。


var obj: Vector = new Vector();
console.log(obj.x, obj.y);  // 0 0
obj.length = 2;
obj.angle = Math.PI / 6;
console.log(obj.length, obj.angle * Point.RAD_TO_DEG);  // 2 29.999999999999996

02 メソッドの引数が省かれたときの処理を定める

サブクラス(Vector)には。座標に定数値を乗じて伸縮させるメソッド(scale())が備わっています。この乗数の引数として、xyそれぞれ別の値が渡せるように書き替えてみました。


class Vector extends Point {

	// scale(scale): void {
	scale(scaleX: number, scaleY: number): void {
		this.x *= scaleX;  // scale;
		this.y *= scaleY; // scale;
	}

}

メソッド(scale())に渡したふたつの引数は、つぎのようにxy座標それぞれに乗じられます。


var obj: Vector = new Vector(1, 1);
obj.scale(1, Math.sqrt(3));
console.log(obj.length, obj.angle * Point.RAD_TO_DEG);  // 1.9999999999999998 59.99999999999999

もっとも、もとのメソッドと同じように引数ひとつでも使えると便利です。その場合、xyそれぞれに同じ引数値を乗じます。けれど、引数の数が合わないと、つぎのようにエラーが起こります。

Supplied parameters do not match any signature of call target.

引数の後につぎのように?記号を添えると、その引数は省けるようになります。そのうえで、第2引数が渡されないときは、替わりに第1引数の値を用いればよいのです。


class Vector extends Point {

	scale(scaleX: number, scaleY?: number): void {
		this.x *= scaleX;
		this.y *= (isNaN(scaleY) ? scaleX : scaleY); // scaleY;
	}

}

これで、メソッドに引数をひとつだけ渡して呼び出したとき、xy座標に同じ引数値が乗じられます。


var obj: Vector = Vector.polar(1, Math.PI / 3);
obj.scale(2);
console.log(obj.length, obj.angle * Point.RAD_TO_DEG);  // 2 59.99999999999999

03 定数を定める

スーパークラス(Point)には、静的プロパティ(RAD_TO_DEG)としてラジアンから度数への変換比率が納められています。この値はつねに変わりません。けれど、publicのプロパティですので、つぎのように書き替えができてしまいます。


var obj: Vector = Vector.polar(1, Math.PI / 3);
Point.RAD_TO_DEG = 0;
console.log(obj.length, obj.angle * Point.RAD_TO_DEG);  // 1 0

TypeScriptはキーワードconstで、以下のように定数が宣言できます。この値を書き替えようとすると、つぎのようにそれはできないというエラーが示されます。

Left-hand side of assignment expression cannot be a constant.

const RAD_TO_DEG: number = 180 / Math.PI;
var obj: Vector = Vector.polar(1, Math.PI / 3);
RAD_TO_DEG = 0;
console.log(obj.length, obj.angle * Point.RAD_TO_DEG);

ただし、クラスのプロパティにconst宣言は使えません。つぎのようにエラーが出てしまいます。

A class member cannot have the 'const' keyword.

でも、書き替えできないプロパティは定められます。つぎのように、getアクセサを用いればよいのです。setアクセサがないかぎり、この値は変えられません。ただし、書き替えようとしても、ビルドでエラーは起こらないことにお気をつけください。


class Point implements IPoint {
	// static RAD_TO_DEG: number = 180 / Math.PI;

	static get RAD_TO_DEG(): number {
		return 180 / Math.PI;
	}

}


var obj: Vector = Vector.polar(1, Math.PI / 3);
Point.RAD_TO_DEG = 0;
console.log(obj.length, obj.angle * Point.RAD_TO_DEG);  // 1 59.99999999999999

TypeScriptコードをまとめるとつぎのとおりです(コード001)。また、以下にサンプル001としてCodePenに書いたコードを掲げてあります。

コード001■メソッド引数にデフォルト値と省略時の処理および定数を定める


class Point implements IPoint {
	constructor(public x: number = 0, public y: number = 0) {
	}
	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 get RAD_TO_DEG(): number {
		return 180 / Math.PI;
	}
	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 = 0, y: number = 0) {
		super(x, y);
	}
	scale(scaleX: number, scaleY?: number): void {
		this.x *= scaleX;
		this.y *= (isNaN(scaleY) ? scaleX : scaleY);
	}
	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: Default and optional parameters and a read-only property

See the Pen TypeScript: Default and optional parameters and a read-only property by Fumio Nonaka (@FumioNonaka) on CodePen.


作成者: 野中文雄
更新日: 2016年9月23日 TypeScriptのバージョンを2.0.3に更新。
作成日: 2016年9月14日


Copyright © 2001-2016 Fumio Nonaka.  All rights reserved.