What is VEJIS

VEJIS is a JavaScript library for "grammar level" enhancing. With VEJIS, one can easily create and use namespaces and define powerful VEJIS classes.

Namespace System

So, as JavaScript is no longer just a way to deal with simple AJAX things, you may find the number of your code become bigger and bigger. We do except a better way to organize our code and code files.

That's accurately what VEJIS can bring to you!

VEJIS namespace system provides 3 methods to create, load and use the related file and namespace.

//create a namespace named "vilic".
namespace_('vilic', function () {
    this.test = function () { };
});

//now we know the namespace "vilic" and function "test" are created immediately,
//so, let's call the function "test".
vilic.test();

//sometimes, it may be hard to know when will the namespace be created,
//but it would be very easy with "use_".
use_('vilic', function (vilic) {
    vilic.test();
});

//what if a namespace is created in another file?
//try this.
require_('vilic.alpha.js', function (alpha) {
    //some other code.
});

As what you see, the 3 methods are "namespace_", "use_" and "require_", and you may want more about them.

  • namespace_(name : string, body : function)

    Create a namespace. The namespace will be created only if it's parent namespace has been created. For example, namespace "vejis.alpha" will be created only if namespace "vejis" has been created. Otherwise, it would be added into a queue, once the parent namespace is created, it would be created immediately.

    In a namespace body, one can also use the 3 methods with "this", and the "path" is relative.

    namespace_('vilic', function () {
        //this == vilic;
        var that = this;
    
        this.namespace_('alpha', function () {
            //this == vilic.alpha;
        });
    
        this.use_('alpha', function (alpha) {
            //this == that;
            //alpha == vilic.alpha;
        });
    
        //namespace that starts with a "." is absolute.
        this.use_('.vilic.alpha', function (alpha) {
            //this == that;
            //alpha == vilic.alpha;
        });
    
        this.require_('somefile.js', function (ns) {
            //this == that;
        });
    });
    

    But what about the arguments the "namespace_" send in? They, if exists, will be the parent namespaces, like below.

    namespace_('grand.parent.of.vilic', function (grand, parent, of) {
        //this == vilic;
    	//grand == global.grand;
    	//parent == grand.parent;
    	//of == grand.parent.of;
    });
    
  • use_(namespace : string [, namespace_args : string], body : function)

    You can use one or more namespaces at the same time, and the namespace objects will be the parameters in order for "body" when callback.

    use_('vilic.aaa', 'vilic.bbb', function (aaa, bbb) {
        //aaa == vilic.aaa;
        //bbb == vilic.bbb;
    });
    

    The "use_" method won't send any request to get a script file. If the namespaces are not yet ready, it will add them to a queue, and once the namespaces needed are ready, the "body" will be called immediately.

    Then, how about use it like this?

    use_('dom', 'dom.event').
    namespace_('grand.parent.of.vilic', function (dom, event, grand, parent, of) {
        //this == vilic;
    	//dom == global.dom;
    	//event = dom.event;
    	//grand == global.grand;
    	//parent == grand.parent;
    	//of == grand.parent.of;
    });
    
  • require_(url : string [, url_args : string][, body : function])

    The "require_" method will try to get the JS files and execute them, then, it's actually quite like "use_". But the JS file to require has some rules. It must be written like this.

    namespace_('somename', function () {
        //code...
    });
    

    If you just want to require a file but not to use it right now, you can ignore the "body", and use "use_".

    require_('somename.js');
    
    //when you want to use it, use "use_".
    use_('somename', function (somename) {
        //code...
    });
    

    And notice that the path is relative to the script file when you use "require_".

    //this is "dir/file-a.js"
    namespace('a', function () {
        //code...
    });
    
    //this is "dir/file-b.js"
    namespace('b', function () {
        //require "file-a.js", notice, without "dir/"
    	this.require_('file-a.js');
    });
    
    //this is a script file in root directory.
    require_('dir/file-b.js');
    

You may want to debug sometimes, right? By now, it's still a simple part of VEJIS. But not that simple. On the one hand, VEJIS deals with stacks information on some browsers, and it will help you to locate the errors more efficiently. On the other hand, you can use "vejis.status" method to get some information about the namespaces and file requiring.

//find out the status of your namespaces.
//and it will log the information like below:
//status - namespace name
//"status" here stands for "created" or "waiting".
vejis.status('namespace');

//find out the status of your requiring.
//and it will log the information like below:
//status - file name
//"status" here stands for "loaded", "loading", "load error" or "exec error".
vejis.status('require');
Class Enhancing

Actually it's the core function of the older VEJIS. Before this, VEJIS was focusing on method overloading, but in the new one, there's nothing about the method overloading any more. But the support for class enhancing has never been decreased.

There are some features of VEJIS class.

  • Basic usage.
    var A = class_(function () {
    	//define constructor.
    	this._(function (value) {
    		this.value = value;
    	});
    
    	//define a property.
    	this.value = 0;
    
    	//define a method.
    	this.test = function () {
    		alert(this.value);
    	};
    });
    
    var a = new A(123);
    //a.value == 123;
    
    a.test(); //alert(123);
    
  • Static public and private objects.
    var A = class_(function (pub, pri) {
    	this.set = function (value) {
    		pri.priValue = value || 456;
    	};
    
    	this.get = function () {
    		return pri.priValue;
    	};
    }).static_(function () {
    	//define static public properties, optional.
    	this.public_({
    		pubValue: 'pub'
    	});
    
    	//define static private properties, optional.
    	this.private_({
    		priValue: 'pri'
    	});
    });
    
    //the static public properties will be copied to the class "A".
    //A.pubValue == 'pub';
    
    var a1 = new A();
    var a2 = new A();
    
    a1.set(123);
    //a2.get() == 123;
    
    //actually, if you only want static private properties, you can use something like this.
    var C = class_(function (pub, pri) {
        //code...
    }).static_({
        priValue: 'pri'
    });
    

    You may notice the static public object "pub", there are some differences between it and the "A", namely the class. Actually when it's a base class of inheriting. So, one should always use "pub" but not "A" to access static public properties.

  • Inheriting.
    var B = class_(function (pub, pri) {
    	this.getFromB = function () { return pri.priValue; };
    }).inherit_(A);
    
    var a = new A();
    var b = new B();
    
    //call the method defined in class A from the two instances.
    a.set(987);
    b.set(789);
    
    //a.get() == 987;
    //b.get() == 789;
    //b.getFromB() == 789;
    

    This example shows some relationship of the private objects in class "A" and class "B": they are individual. And so are the public objects. So, don't worry about your changes to a new class on the two objects would influence the old ones (the premise is, you are using the objects "pub" and "pri").

Method Enhancing

I was so cruel to it! And now it's no longer a powerful stuff of VEJIS. You can use it to create a method with static variables. I know it's simple.

//the first argument is the static object, and it's private.
var fn = _(function (st, n) {
	console.log(st.count += n);
}).static_({
	count: 0
});

//get something to n.
fn(1);
fn(2);
Something else

You may notice every method of vejis ends with a "_", I guess there might be many people who don't like this style, but they will. When VEJIS is created, as what was mentioned, its core function is method overloading. I wanted a mark that is brief and clean enough to create a VEJIS method, and finally I chose "_", the grammar was like this.

//notice, this function has already been removed, so, it's no longer available.
//as for why, I think it was that the overloading stuffs cost too much.

//create a VEJIS method.
var fn = _(String, Number, function (str, num) {
    //code...
});

//overload method fn.
fn._(Boolean, function (b) {
    //code...
});

Actually, with that code, one is able to create a class with multiple constructors. But sometimes, the things we should change may be only lines, if we use a way like that, a constructor would need to be rewritten totally. So I wanted to create a function to solve this problems. You know that the word "class" is one of JavaScript's key word, so I simply added a "_", and made it "class_".

As VEJIS is a "grammar level" enhancing, there're chances that the words it use may conflict with some key words. So, the suffix "_" became a common rule for methods defined by VEJIS.