如何创建一个小型Javascript扩展语言
How to create a small Javascript extension language?
我最近重构了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
和bar,而无需键入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
必须使用WIDGETS.hello()
)。
我尝试使用ERB(我在Rails上)创建这个模式,但结果很混乱。因此,我正在考虑为此编写一个小型的源代码到源代码编译器,比如CoffeeScript(具有SASS的最小差异/扩展语言哲学),它只编译一些函数来替代javascript。
我只想要一个速记。
例如,这将编译到上面的第二个代码块:
//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**
});
简单而小巧——这样你就不需要跟踪变量了。我还想像这样分离命名空间(这样我就可以将其拆分为多个文件):
APP = NAMESPACE(function() {
var x,y,z;
function foo() {}
function bar() {}
//**notice the missing return statement that I don't need to manage and map to my variables**
});
APP = NAMESPACE(function() {
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**
});
});
有什么想法吗?我不确定所有的东西,但我想如果存在的话,我会更喜欢Javascript。
您可能想要了解的内容:
- 水仙:https://github.com/mozilla/narcissus/
- Traceur:http://code.google.com/p/traceur-compiler/
- 反射.js:https://github.com/zaach/reflect.js
- http://www.mascaraengine.com/doc/languagewalk
- https://github.com/jashkenas/coffee-script/wiki/List-of-languages-that-compile-to-JS
还有一个关于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
}
})();
您所描述的是通常所说的"模块模式"。这很好,因为您可以定义"隐藏"且无法访问的内部方法和变量。它也不会污染全局命名空间。你可以在这里阅读更多关于它的信息(我相信这是关于这项技术的第一篇文章之一。)也可以在这里和这里阅读。
然而,由于你把所有事情都"公开"了,它就没有那么有用了。你可以这样做(包括测试代码):
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();
而且你可以用更少的语法得到同样的效果。
http://jsfiddle.net/ZwCUh/
顺便说一句,有一些方法可以在没有编译器的情况下编写代码,通过原型可以让你接近你想要的东西。一个很好的例子是jQueryUI的源代码。我相信其他库(原型、moo工具等)也可以用作示例。
- 为什么不't Javascript对我的输入值进行了一些重新检查
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 将函数的上下文应用于javascript变量
- 使用php或javascript从facebook相册URL中删除多余的部分
- 正在添加'X'按钮,在文本字段旁边使用javascript
- 如何在JavaScript中将字符串转换为函数引用
- 模糊事件的Javascript测试
- Javascript更改图标
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 如何使用WCF服务和javascript表单post上传.doc文件
- 将一个小型javascript表达式转换为mongodb查询
- 小型JavaScript动画集成
- 如何创建一个小型Javascript扩展语言
- 使用 JSON 文件在 javascript 中持久存储小型数据库
- 小型JavaScript解决方案需要:此行是否有效代码
- 小型JavaScript悬停滑块图片库在Firefox中不起作用
- 在生产环境中使用Chrome调试小型JavaScript
- 对于小型的自包含事件处理函数,可以使用内联javascript吗
- 一个拥有许多优秀和小型javascript库的网站
- 小型,快速,客户端Javascript数据库'功能