我更喜欢使用有时被称为“揭示模块”(...模式)的东西。看起来像:
var Engine = (function($)
{
$ = $ || {};
var someVar = 4;
$.Scene = function()
{
this.entities = [];
}
$.Scene.prototype.render = function()
{
// this function can access someVar just fine because of JavaScript's scoping rules
}
return $;
})(Engine);
这使用所谓的立即调用函数表达式(以下称为IIFE)在 Engine 对象内形成一个闭包。由于JavaScript 对范围的处理, IIFEsomeVar
中定义的任何函数都可以访问。someVar
但是,这意味着如果要引用someVar
您在 IIFE 中定义的函数,则没有函数可以定义自己的函数。
魔术来自 return 语句。您可以看到返回了一个对象,并且在此对象中您必须定义任何您想要“公开”的内容。
然后可以通过 访问构造函数、实用程序方法等Engine.Scene
,这很好地为您的代码命名空间。
至于$
参数,这样您就可以传递Engine
给每个文件中的函数,添加一些方法/属性/构造函数(如果不存在则创建一个新的),然后将返回值传递给另一个 IIFE 以进一步扩张。
这是许多流行的 JavaScript 框架中使用的方法,包括jQuery、dojo和LimeJS
场景.js:
var Engine = (function ($) {
// this creates a new object if Engine is undefined in the
// invocation below, and keeps the old object otherwise.
// alternatively: if ($ === undefined) { $ = new Object; }
$ = $ || {};
$.foo = "foo";
$.Scene = function () {
// blah blah
}
// Engine holds either a newly created object,
// or the old one if it was already defined
return $;
})(Engine);
sprite.js:
var Engine = (function ($) {
$ = $ || {};
$.Sprite = function () {
// totally works
this.bar = $.foo;
}
return $;
})(Engine);
然后,您可以将它们与以下内容一起使用:
<script type="text/javascript" src="bar.js"></script>
<script type="text/javascript" src="foo.js"></script>
<script type="text/javascript">
var mySprite = new Engine.Sprite;
var myScene = new Engine.Scene;
</script>
你可以$
用任何你喜欢$$
的、常见的或聪明的代替。它只是您要添加到的全局对象的占位符。