コンストラクタを作成する際、コンストラクタ内でグローバル情報をセットする場合は注意が必要です。例えば、一意的な ID をそれぞれの新しい従業員情報に自動的に代入したいとします。そこで以下のように Employee を定義します。
var idCounter = 1;
function Employee (name, dept) {
this.name = name || "";
this.dept = dept || "general";
this.id = idCounter++;
}
この定義を用いると、新しい Employee を作成するときに、コンストラクタに次の ID が順々に代入され、グローバル ID カウンタがインクリメントされます。その結果、以下の文を続けると victoria.id は 1 になり harry.id は 2 になります。
victoria = new Employee("Pigbert, Victoria", "pubs")
harry = new Employee("Tschopik, Harry", "sales")
一見これは申し分なさそうです。しかし、idCounter はどんな用途であろうと Employee オブジェクトが作成されるたびにインクリメントされます。この章で示した Employee の階層全体を作成すると、Employee コンストラクタはプロトタイプをセットアップするたびに呼び出されます。次のコードを想定します。
var idCounter = 1;
function Employee (name, dept) {
this.name = name || "";
this.dept = dept || "general";
this.id = idCounter++;
}
function Manager (name, dept, reports) {...}
Manager.prototype = new Employee;
function WorkerBee (name, dept, projs) {...}
WorkerBee.prototype = new Employee;
function Engineer (name, projs, mach) {...}
Engineer.prototype = new WorkerBee;
function SalesPerson (name, projs, quota) {...}
SalesPerson.prototype = new WorkerBee;
mac = new Engineer("Wood, Mac");
さらに、ここでは省かれている定義に base プロパティがあり、その定義がプロトタイプチェーンにおいて上位のコンストラクタを呼び出すとします。この場合、mac オブジェクトが作成されるまでに mac.id が 5 になります。
カウンタが余計にインクリメントされることが問題になるかならないかは、そのアプリケーション次第です。このカウンタの正確な値が必要であれば、代わりに次のコンストラクタを使うという 1 つの解決策が考えられます。
function Employee (name, dept) {
this.name = name || "";
this.dept = dept || "general";
if (name)
this.id = idCounter++;
}
プロトタイプとして使用するために Employee のインスタンスを作成するときはコンストラクタに引数を与えてはいけません。このコンストラクタの定義では、引数を渡さないときはコンストラクタが値を id に代入せず、カウンタを更新することもありません。そのため、Employee が id に値を代入するようにするときは従業員の名前を指定する必要があります。この例では mac.id は 1 になります。
Page last modified 12:10, 2007年5月28日 by Mgjbot