我最近重构了我的JS代码并偶然发现了这种模式:
APP = (function() {
var x,y,z;
function foo() {}
function bar() {}
return {x:x, y:y, z:z, foo:foo: bar:bar};
})();
这样做的好处是它创建了非全局变量,其中的函数可以访问APP
中定义的所有内容。因此,APP.foo
可以访问x, y, z
,并且无需键入APP.bar()
,APP.x
等即可停用。还可以使用APP.bar()
,APP.x
全局访问所有内容等等你也可以嵌套它们:
APP = (function() {
var x,y,z;
function foo() {}
function bar() {}
var WIDGETS = (function() {
var a,b,c;
function hello() {}
function world() {}
return {a:a, b:b, c:c, hello:hello, world:world};
})();
return {x:x, y:y, z:z, foo:foo: bar:bar, WIDGETS:WIDGETS};
})();
因此WIDGETS
可以访问APP
中的变量,但反之亦然(APP.WIDGETS.hello
可以使用foo()
,但APP.foo
必须使用{{} 1}})。
我尝试使用ERB(我在Rails上)创建这个模式,但结果却很混乱。所以我正在考虑为此编写一个小的源到源编译器 - 像CoffeeScript(具有SASS的最小差异/扩展语言哲学),它只是将一些函数编译成替代的javascript。
我只想要一个速记。
例如,这将编译到我上面的第二个代码块:
WIDGETS.hello()
简单和小 - 只是因此您不需要跟踪变量。还希望将命名空间分开(因此我可以将其拆分为多个文件):
//NAMESPACE is a magical function I compile down to the long version in the second code block
APP = NAMESPACE(function() {
var x,y,z;
function foo() {}
function bar() {}
var WIDGETS = NAMESPACE(function() {
var a,b,c;
function hello() {}
function world() {}
//**notice the missing return statement that I don't need to manage and map to my variables**
});
//**notice the missing return statement that I don't need to manage and map to my variables**
});
有关如何做到这一点的任何想法?我不确定一切,但我认为如果存在,我会更喜欢Javascript。
答案 0 :(得分:1)
您可能想要了解的事情:
还有一项关于EcmaScript 6中模块系统的建议,将来可以使用:http://wiki.ecmascript.org/doku.php?id=harmony:modules
现在,如果目标只是输入foo()
而不是APP.foo()
,那么我认为创建javascript的语言超集有点紧张......
如果您使用CoffeeScript导出,那么变量就不那么详细了:
APP = do ->
[x,y,z] = []
foo = ->
bar = ->
WIDGETS = do ->
[a,b,c] = []
hello = ->
world = ->
{ a, b, c, hello, world }
{ x, y, z, foo, bar, WIDGETS }
在实践中,你很少导出每个变量,事实上你们中的一些变量是“私有的”。您还可以在对象内部定义函数:
APP = (function() {
var x,y,z;
var WIDGETS = (function() {
var a,b,c;
return {
hello: function hello(){},
world: function world(){}
}
})();
return {
foo: function foo(){},
bar: function bar(){},
widgets: WIDGETS
}
})();
答案 1 :(得分:0)
您所描述的是通常所谓的“模块模式”。这很好,因为您可以定义“隐藏”且无法访问的内部方法和变量。它也不会污染全局命名空间。您可以阅读更多相关信息here(我相信这是关于该技术的第一篇文章之一。)另外here和here。
然而,既然你把所有东西都“公之于众”,那就不那么有用了。你可以这样做(包括测试代码):
APP = function (me) {
me.x = 0;
me.y = 0;
me.z = 0;
me.foo = function () { alert(me.x); },
me.bar = function () {};
WIDGETS = function (me2) {
me2.a = 0;
me2.b = 0;
me2.c = 0;
me2.hello = function () {};
me2.world = function () {};
return me2;
}({});
return me;
}({});
APP.x = 1;
APP.foo();
使用较少的语法可以获得相同的效果。
作为旁注,有一些方法可以在没有编译器的情况下编写代码,使您能够通过原型接近您所寻找的内容。一个很好的例子是jQueryUI的源代码。我确信其他库(原型,moo工具等)也可以用作示例。