仮引数とクロージャ2007年05月04日 02時58分41秒

(元記事:ある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

コメント

_ fnya ― 2007年05月04日 14時28分09秒

はじめまして。fnyaと申します。

プライベートフィールド/メソッドが使用できることを示す
ためのサンプルではありましたが、確かに冗長ですね。
これからサンプルを作成する際に気をつけたいと思います。

ご指摘ありがとうございました。

_ dara-j ― 2007年05月04日 15時25分05秒

fnyaさん、わざわざコメントありがとうございます。

>これからサンプルを作成する際に気をつけたいと思います。
いえいえ、とんでもない。
他の言語からすると、引数とローカル変数を同様に扱えること
自体が変な感覚になると思うので、宣言するほうがわかりやすい
かなとは思いますが、個人的には識別子は少ないほうが混乱が
少ないと考えて、極力変数宣言をさける傾向があるので
ちょっと書いてみました。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://dara-j.asablo.jp/blog/2007/05/04/1482262/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。