仮引数とクロージャ
2007-05-04


(元記事:あるSEのつぶやき: prototype.jsでプライベートメソッドを持つクラスを作る方法

ローカル変数の代わりに

個人的には最近まったく使わなくなっていた「JavaScriptによるプライベートフィールドの隠蔽」だが、あるSEのつぶやきさんが取り上げていたので一言(でもないか)。

リンク先記事で、Animal#defineメソッド内の実装で、プライベートフィールドをわざわざ定義しているが、これって、defineメソッドの仮引数「_sex」を_getSexで囲っちゃっても同じなんだよね。

15:     define : function(_sex) {
16:             //プライベートフィールド
17://           var sex = _sex; // ←コメントアウト
18:
19:             //プライベートメソッド
20:             var _getSex = function() {
21:                     return _sex;// ←変更。仮引数にアクセスできるし。
22:             }
23:
24:             //Privileged(特権)メソッド
25:             this.getSex = function (){
26:                     return Animal.SEXTYPE[_getSex()];
27:             }
28:     }
仮引数も、関数内でvar宣言されたローカル変数も、このメソッド内の実行コンテキストにバインドされた変数オブジェクトのプロパティであることには変わりがないので、宣言するだけ冗長かと。

同じIdentifierの仮引数とローカル変数の関係を見るために以下のコードを検証してみた。

function test1() {
        var a;
        return "test1: " + a;
}

function test2(a) {
        return "test2: " + a;
}

function test3(a) {
        var a;
        return "test3: " + a;
}

alert( test1("hoge") ); // 'test1: undefined'
alert( test2("hoge") ); // 'test2: hoge'
alert( test3("hoge") ); // 'test3: hoge'
Firefox1.5でしか試していないが、たぶんどの処理系でも同じだと思う。ポイントはtest2とtest3の結果が同じになること。 ついでだが、test3内でローカル変数宣言に代入式を与えると、当然仮引数「a」はオーバーライドされるので、違う結果になる。

おまけ

この手の解説で、以前は「Effective JavaScript」というよいコンテンツがあったのだが、現在は公開されていない。非常に残念だ。

現在はアクセスしても404になるのでリンクはせず、当時のURLを掲載しておく。www.archive.orgなんかを利用するとまだ確認できるかも。

http://www.interq.or.jp/student/exeal/dss/ejs/index.html
[JavaScript]

コメント(全2件)
コメントをする


記事を書く
powered by ASAHIネット