JavaScriptで名前空間のようなもの
http://d.hatena.ne.jp/nazoking/20050425/1114374966 に関連して、名前が短いもの( $ とか、O とか X とか)も、ぶつかる可能性があるので出来るなら避けて欲しい。まあ、普通はないんだけど。
で、どうしても短い名前を使いたい人用の、オブジェクトを名前空間代わりに使う方法*1。
例えば nazoking という名前空間にいろいろ定義する場合、
if( typeof(nazoking)=='undefined' ) nazoking=new Object; // 定義 nazoking.O = function(){ alert('Oという名前の超便利関数'); }
みたいな感じで。使うときは
var hoge = nazoking.O();
で、もし、名前空間 nazoking をよく使うのであれば
with(nazoking){ // スクリプトの先頭あたりで、この名前空間をよく使うよ宣言 〜 O(); // nazoking.O が呼ばれる 〜 } //スクリプトの最後辺りで、withを閉じる
のよう。そのライブラリを使うかなり広い範囲を、withで囲むといいだろう。withはネストできるので、
with(nazoking){with(whoslib){ O(); // whoslib.O が定義されていなかったら nazoking.O が定義されていなかったらグローバルな O }}
みたいなことも出来る。オブジェクトのプロパティーだけに名前空間を当てはめる、とかは出来ないけど、短い名前の便利関数を使いたい人とかは便利かも。
ただし、
nazoking=new Object; with(nazoking){ val = 'test'; }
こんな書き方をしたときに(nazoking.valが定義されていない場合)、nazoking.valが新しく作られて'test'が代入される、のではなくグローバルの valが新しく作られて代入されるので、ここだけ注意が必要かも。
複雑な動作例
ちなみに
//ここからライブラリ定義 if( typeof(nazoking)=='undefined' ) window.nazoking=new Object; with(nazoking){ nazoking.O = function(msg){ alert(msg); } nazoking.alert=function(){ window.alert('nazoking::'+msg); } } //別のライブラリ(^^;)定義 whoslib={}; //main *************************** with(nazoking){with(whoslib){ // nazoking と whoslib を使うよ O('test'); }}
という感じの場合、mainで O という関数を呼んでいるが、
- whoslib.O は定義されていないのでスルー
- nazoking.O は定義されているので、これが呼ばれる
- nazoking.O の中の alert は、
- それが定義されたときに with(nazoking) されているので
- nazoking.alert が呼ばれる
- nazoking.alert の中では window.alert を呼んでいるので、普通のダイアログが出る。
- nazoking.O の中の alert は、
という大体理想通りの動きをする。
Object オブジェクトの prototype に便利メソッドを放り込むのはやめて頂きたい
JavaScriptの便利系ライブラリで、Object の prototypeにいろいろ放り込むのがあるけど、やめていただきたい。例えば http://prototype.conio.net/ の Object.prototype.extend とか。便利なんだけどね。
Object.prototype.extend = function(object) { for (property in object) { this[property] = object[property]; } return this; }
わかる、わかるよやりたいことは。あれば確かに便利だ。そしてオブジェクト指向の考え方からして、そこにあるべきだろう。
でも、
info={name:"タロウ",tel:"090-xxx-xxx"}; for( i in info ){ document.write( i+"="+ info[i]+"<br>" ); }
とかやったときに、extend も列挙されちゃうんだよ! 実際に問題になることは「少ない」けどさぁ。DontEnum 属性を指定する方法とか無い物か。
で、だから普通に Object_extend とかの関数名で定義されたし。