2007年02月02日 16:45 [Edit]

javascript - ふつうのnamespace

これはいいとして、

IT戦記 - JavaScript の名前空間
シンボルの衝突が非常に大きな問題となる。その代表例が Firefox の拡張機能内のシンボルである。

これはJS界のラマヌジャンなamachangならとにかく、私でも起き抜けにコーヒーの湯気も当たらぬこちこちの頭ではついてけん。

window['http://d.hatena.ne.jp/amachang/']={}; // URI
(function(){with(this){
  // ここにコードを書く
}}).apply(window['http://d.hatena.ne.jp/amachang/']); // URI

これはふつうに

// Namespace jp.ne.hatena.d.amachang a la Java
if (jp == undefined) jp = {};
if (jp.ne  == undefined) jp.ne = {};
if (jp.ne.hantena  == undefined) jp.ne.hantena = {};
if (jp.ne.hantena.amachang  == undefined) jp.ne.hantena.amachang = {};

と律儀にやるか、

function Namespace(str){
  var ns = str.split('.');
  var here = window;
  for (var i = 0, l = ns.length; i < l; i++){
      if (typeof(here[ns[i]]) == 'undefined') here[ns[i]] = {};
      here = here[ns[i]];
  }
  return here;
}

とでもしておいて、

new Namespace('jp.ne.hatena.d.amachang');

とした方がいい。これなら、

(function(){with(this){

  var hoge     = 'hoge'; // このスコープ内で共有するシンボル
  this.fuga    = 'fuga'; // 同じ名前空間で共有するシンボル
  window.piyo  = 'piyo'; // グローバルで共有するシンボル

  alert(hoge); // hoge
  alert(fuga); // fuga
  alert(piyo); // piyo

}}).apply(window['http://d.hatena.ne.jp/amachang/']);

functionで包んでwithを噛ませ尻でapplyするという魔法なしでも、

var ns = new Namespace('jp.ne.hatena.d.amachang');
var hoge     = 'hoge'; // このスコープ内で共有するシンボル
ns.fuga      = 'fuga'; // 同じ名前空間で共有するシンボル
window.piyo  = 'piyo'; // グローバルで共有するシンボル

でいいので、二日酔いの頭でも(って私自身は二日酔いになったためしがないのだけど)何とかついてけるコードになる。

ちなみに、「サイ本」のChapter 10がnamespaceに宛てられていて、推奨しているのがやはりこちらの方法なのだけど、typeof(ns) == 'undefined'じゃなくて!nsでnamespaceの存在判定をしているところがイマイチ。あと、Namespace pseudoconstructor は私の思いつき。ns = jp.ne.hatena.d.amachang;がある限り、withはお役御免でいいと思う。

Dan the Javascripter

追記:ns == undefinedtypeof(ns) == 'undefined'に変更。こちらの指摘に加え、typeof(ns) == 'undefined'の方が下位互換性も高い。definedexistsがないというのもきついものがある。


この記事へのトラックバックURL

この記事へのトラックバック
GoogleMapAPI http://maps.google.comを申請するかhttp://www.google.com/jsapiを申請するかの件 http://maps.google.com GoogleMapに特化したAPIキー http://www.google.com/jsapi RSSやATOMのFeedも取得できる。GoogleMapのAPIも呼び出せる。 http://journal.mycom...
sango/2007-11-10【Sango's Wiki on Topaz (PukiWiki/TrackBack 0.4)】at 2007年11月10日 13:21
最近JavaScriptを勉強?しています。 で、困るのが名前空間をどうすればいいのかということ JavaScript の名前空間 - IT戦記 404 Blog Not Found:javascript - ふつうのnamespace 結局よくわからんので、YUIをパクって if (typeof 'Hoge' === 'undefined' || !Hoge) {...
結局JavaScriptの名前空間はどうすればいいのだろうか?【にひりずむ::しんぷる】at 2009年07月14日 23:44
この記事へのコメント
Namespaceの例だとvar hogeはグローバル汚染するんじゃないでしょうか。
Posted by hoge at 2007年02月02日 18:45
> Namespaceの例だとvar hogeはグローバル汚染するんじゃないでしょうか。
function whatever(){
}
を略記したわけです。
もちろんグローバル(browserの場合にはwindow)汚染が問題でない場合もありますが。
Dan the Javascripter
Posted by at 2007年02月02日 18:59
defined(or exsist) は

'simbol' in window

でできますですよ。
Posted by amachang at 2007年02月02日 21:17
amachang,
あ、なるほど。でもその手はfunction lexicalな変数には使えないのでは?
Dan the Javascripter
Posted by at 2007年02月02日 21:56