簡體   English   中英

是否有一種“簡潔”的方式在JavaScript中進行命名空間?

[英]Is there a “concise” way to do namespacing in JavaScript?

我經常遇到一些網站,它們將所有JavaScript放在namespace結構中:

namespaces = { com : { example: { example.com's data} }

但是,相對於其他命名空間框架安全地設置它似乎需要相對大量的代碼(定義為> 2行)。 我想知道是否有人知道這樣做的簡潔方法? 此外,是否有相對標准/一致的結構方式? 例如, com命名空間是直接附加到全局對象,還是通過命名空間對象附加?

[編輯:哎呀,顯然{com = { ... } }無法完成任何接近我的意圖,感謝Shog9指出這一點。

Javascript沒有獨立的命名空間。 它具有可以提供解析名稱和對象的范圍的功能,這些功能可以對給定范圍內可訪問的命名數據做出貢獻。

這是你的例子,更正了:

var namespaces = { com: { example: { /* example.com's data */ } } }

這是一個賦予對象文字的變量namespaces 該對象包含一個屬性: com ,一個具有一個屬性的對象: example ,一個可能包含有趣內容的對象。

因此,您可以輸入類似namespaces.com.example的內容。 somePropertyOrFunctionOnExample ,它都會工作。 當然,這也是荒謬的。 您沒有分層命名空間,您有一個對象,其中包含一個對象,該對象包含您實際關注的內容。

var com_example_data = { /* example.com's data */ };

這也很有效,沒有毫無意義的層次結構。

現在 ,如果你真的想要構建一個層次結構,你可以嘗試這樣的事情:

com_example = com_example || {};
com_example.flags = com_example.flags || { active: false, restricted: true};

com_example.ops = com_example.ops || (function()
    {
       var launchCodes = "38925491753824"; // hidden / private
       return {
         activate: function() { /* ... */ },
         destroyTheWorld: function() { /* ... */ }
       };
    })();

......恕我直言,相當簡潔。

以下是Peter Michaux關於Javascript Namespacing的一篇有趣文章。 他討論了3種不同類型的Javascript命名空間:

  1. 前綴命名空間
  2. 單個對象命名空間
  3. 嵌套對象命名空間

我不會抄襲他在這里說的話,但我認為他的文章非常有用。

彼得甚至指出,其中一些人有性能方面的考慮。 我認為這個話題很有意思,考慮到新的ECMAScript Harmony計划已經放棄了4.0的命名空間和包裝計划。

我嘗試遵循雅虎慣例,即在全局范圍內制作單個父對象以包含所有內容;

var FP = {};
FP.module = {};
FP.module.property = 'foo';

要確保不覆蓋現有對象,您應該這樣:

if(!window.NameSpace) {
    NameSpace = {};
}

要么

var NameSpace = window.NameSpace || {};

這樣,您可以將它放在應用程序/網站中每個文件的頂部,而不必擔心覆蓋命名空間對象。 此外,這將使您能夠單獨為每個文件編寫單元測試。

YUI庫庫具有使用您可能更喜歡的函數處理命名空間的代碼。 其他圖書館也可以這樣做。

我也喜歡這個( 來源 ):

(function() {
    var a = 'Invisible outside of anonymous function';
    function invisibleOutside() {
    }

    function visibleOutside() {
    }
    window.visibleOutside = visibleOutside;

    var html = '--INSIDE Anonymous--';
    html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
    html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
    contentDiv.innerHTML = html + '<br/><br/>';
})();

var html = '--OUTSIDE Anonymous--';
html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
contentDiv.innerHTML += html + '<br/>';​

作為點或下划線的替代,您可以使用美元符號字符:

var namespaces$com$example = "data"; 

使用對象文字以及this對象或顯式名稱來根據包含該函數的局部變量的同級屬性執行命名空間。 例如:

 var foo = { bar: function(){return this.name; }, name: "rodimus" } var baz = { bar: function(){return this.name; }, name: "optimus" } console.log(foo.bar()); console.log(baz.bar()); 

或者沒有顯式name屬性:

 var foo = { bar: function rodimus(){return this; } } var baz = { bar: function optimus(){return this; } } console.log(foo.bar.name); console.log(baz.bar.name); 

或者不使用this

 var foo = { bar: function rodimus(){return rodimus; } } var baz = { bar: function optimus(){return optimus; } } console.log(foo.bar.name); console.log(baz.bar.name); 

使用RegExpObject構造函數將名稱屬性添加到計數器變量和其他常用名稱,然后使用hasOwnProperty測試進行檢查:

  var foo = RegExp(/bar/); /* Add property */ foo.name = "alpha"; document.body.innerHTML = String("<pre>" + ["name", "value", "namespace"] + "</pre>").replace(/,/g, "&#09;"); /* Check type */ if (foo.hasOwnProperty("name")) { document.body.innerHTML += String("<pre>" + ["foo", String(foo.exec(foo)), foo.name] + "</pre>").replace(/,/g, "&#09;"); } /* Fallback to atomic value */ else { foo = "baz"; } var counter = Object(1); /* Add property */ counter.name = "beta"; if (counter.hasOwnProperty("name")) { document.body.innerHTML += String("<pre>" + ["counter", Number(counter), counter.name] + "</pre>").replace(/,/g, "&#09;"); } else { /* Fallback to atomic value */ counter = 0; } 

DOM使用以下約定來命名HTML和SVG Element接口定義:

  • HTMLTitleElement
  • SVGTitleElement
  • SVGScriptElement
  • HTMLScriptElement

JavaScript核心使用原型將toString方法命名為一種簡單形式的多態。

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM