How to create a small Javascript extension language?

I recently processed my JS code and came across this template:

APP = (function() { var x,y,z; function foo() {} function bar() {} return {x:x, y:y, z:z, foo:foo: bar:bar}; })(); 

The advantage of this is that it creates non-global variables with functions that have access to everything that is defined in APP . This way APP.foo can access x, y, z and the bar without entering APP.bar() , APP.x , etc. Everything can also be obtained globally using APP.bar() , APP.x , etc. You can also nest them:

 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}; })(); 

So WIDGETS will have access to variables in APP , but not vice versa ( APP.WIDGETS.hello can use foo() , but APP.foo should use WIDGETS.hello() ).

I tried to create this template using ERB (I'm on Rails), but it turned out to be dirty. So I'm thinking of writing a small source for the source for this - something like CoffeeScript (with a minimal difference / extended SASS language philosophy) that just compiles several functions for alternative javascript.

I just want a shorthand.

For example, this will compile for my second code above:

 //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** }); 

Simple and small - you just don’t need to track variables. I would also like to split the namespace this way (so that I can split it into multiple files):

 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** }); }); 

Any thoughts on how to do this? I'm not sure about everything, but I think that if it existed, I would like Javascript to be much larger.

+8
javascript closures namespaces coffeescript
source share
2 answers

Things you might want to learn:

There is also a proposal for a modular system in EcmaScript 6, which may become available in the future: http://wiki.ecmascript.org/doku.php?id=harmony:modules

Now, if the goal is only to set foo() instead of APP.foo() , then I think the creation of the javascript language superset is a bit stretched ...

If you are using CoffeeScript export, the variables are less verbose:

 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 } 

In practice, you rarely export each variable, because some of them will be "private". You can also define functions inside the object itself:

 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
source share

What you are describing is what is often referred to as the “module template”. This is good because you can define internal methods and variables that are "hidden" and cannot be accessed. It also does not pollute the global namespace. You can learn more about this here (I believe that this was one of the first articles about technology.) Also here and here .

However, since you make everything “public”, this is not so useful. You can do it like this (including test code):

 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(); 

And you will get the same effect with less syntax.

http://jsfiddle.net/ZwCUh/


As a side note, there are ways to write code without a compiler, which allows you to get closer to what you are looking for using prototypes. A good example is the source code for jQueryUI. I am sure that other libraries (prototypes, moo tools, etc.) can also be used as examples.

0
source share

All Articles