The aim of Classing{js}
is to create an object oriented environment that looks and behaves exactly like the classical object oriented environment.If you developed in a classical environment before (like C++ , Java or C#), you know that you can overload the constructor of the class to intialize the objects in differnt ways, including the way using an existing object of the same class (known as the copy constructor).So, to fully achive the aim of Classing{js}
, function overloading was implemented to give the developer the ability to overload the constructors of classes and any other functions wanted.
Creating an overloaded function is done by calling the function Function.create
in the way specified here , in the black box with the red gear:
The mode of Overloading :typed or non-typed.true
for typed , false
for non-typed
an array containing the overloads.
the overloaded function
An example of non-typed overloading is the function say
defined in the following :
var say = Function.create(false , [ function(msg1) { console.log(msg1); }, function(msg1 , msg2) { var concat = msg1 + " , " + msg2; console.log(concat); }, function(msg1 , msg2 , msg3 , msg4) { var concat = msg1 + " , " + msg2 + " , " + msg3; console.log(concat); } ]);
say
here has three instances that accepts one argument, two arguments and four arguments respectively with no restriction on the type of the argument passed. You can pass numbers , strings , objects or any thing and no error will be thrown.The only case an error will be thrown is if you passed a number of arguments that has no instance in the function. Namely , if you passed four or more , two or no arguments , an error will be thrown idicating that no instance matches the argument list.
say("Hi"); //Ok say("Hi" , 5); //Ok say("Hi" , "Welcome" , "to Classing{js}" , 1) //Ok say(); //Error say("Hi" , "Welcome" , "to Classing{js}"); //Error sya("Hi" , "Welcome" , "to Classing{js}" , "v" , 1 , "." , 0); //Error
To make the code more readable , the library provides the constnat classing.xNonTyped
which is equal to false
that can be passed as the first argument to Function.create
indicating a non-typed overloading mode. As this constant is expectd to be used repeatedly, a global shortcut is provided so it could be written fast without calling it from the classing
namespace.
var add = Function.create(xNonTyped , [function(a,b){return a+b;} , function(a,b,c){return a+b+c;}]);
var join = Function.create(xNonTyped , [function(a,b){return a + "," + b;} , "function(){}"]); //Error
var echo = Function.create(xNonTyped , [function() {return "Void";} , function(a){return a;} , function(b) {return "'" + b + "'";}]); //Error
The syntax to create a typed overloaded function is similar to that of non-typed but with a little difference in the format of the overloads array. To fully define an overload instnace you'll need two elements of the array , the first one to hold the types list and the one that follows it to hold the function itself.the type list is created through the function classing.types
.There's also a global shortcut for that function.
the constructor function of the type (either native or custom)
the type list object to be passed to Function.create
For example , to write a type list of a function , a boolean value , an array , a string and finally a number , we write:
types(Function , Boolean , Array , String , Number)
A correct-formated overloads array follows this pattern : the type list comes first , then in the next element comes the function associated with that type list (The number of types and the number of paramters in the associated function must be equal). Note that any overloads array not in this format will throw an error. An example of a typed overloaded function is the add
function defined in the following:
//a Custom type represnting complex number function Complex(r , i) { this.real = r; this.imaginary = i; } var add = Function.create(true , [ types(Number,Number) , function(a , b) { return this.a + this.b; }, types(Array , Array), function(A , B) { if(A.length === B.length) { var C = new Array(A.length); for(var i = 0 ; i < A.length ; i++) { C[i] = A[i] + B[i]; } } }, types(Complex,Complex), //the custom type function(Z , W) { return new Complex(Z.real + W.real , Z.imaginary + W.imaginary); } ]);
Here , add
has three instances , each of which accepts two arguements but with different types. the first one accepts two numbers , the second accepts two arrays and the last one accepts two objects of the type Complex (which is a custom type). Any call to add
with an argument list matching a defined instances in both number and types will work fine. Any call with an argument list that doesn't match any defined instance will throw an error.
add(40,89.69); //Ok add([1 2 3] , [-1 0 9.678]); //Ok add(new Complex(7 , 0) , new Complex(1 , -6)); //Ok add(80); //Error add(80,"Hello"); //Error add([1 4 7] , new Complex(7 , 52)); //Error
Like in non-typed overloading , the library provides the constnat classing.xTyped
which is equal to true
to be passed as the first argument of Function.create
indicating a typed overloading mode. An xTyped
global shortcut is also provided.
var divide = Function.create(xTyped , [types(Number , Number) , function(a , b) {return a / b;}]);
The following are the categories of types that can automatically be recognized in the typed overloading mode:
Classing{js}
Classesfunction <constructorName>(a,b,c,...){ ... }
For custom types that has a constructor of the form:
var <constructorName> = function(a,b,c, ...) { ... }
a stamping step must be made before Classing{js}
can recognize it. the stamping is done using the function classing.xStamp
the custom constructor function to be stamped
For example:
var Human = function(a) { this.age = a; } classing.xStamp(Human); var add = Function.create(xTyped , [ types(Human,Human), function(H1,H2) { return new Human(H1.age + H2.age); } ]); add(new Human(41) , new Human(16)); //Ok