Sunday, May 20, 2007

JavaStrict - Strict Type arguments / returned values with JavaScript

I've just uploaded on devpro my last experimental (stable) function, called JavaStrict.

What is JavaStrict goal?
JavaStrict allows developers to add Strict Type in every kind of function or method, with or without prototype.

Strict Type should be used for function arguments or for its returned value.

JavaStrict static methods just create a function wrapper that will check automatically if arguments or returnValue are exactly specified instances.


How does JavaStrict work?
JavaStrict function has 3 public static methods:

  • apply, to set Type of each accepted argument using an array as second one

  • call, to set one or more valid Type manually

  • returnValue, to set a valid returned value Type




Examples

// showMe is a basic function
function showMe(str){
alert(str);
};

// I need that single argument is a string instance
// (new String("abc") or "abc" works correctly)
showMe = JavaStrict.call(showMe, String);

// test them
try {
showMe("Hello Strict!"); // Ok
showMe(1); // Error!
}
catch(e) {
alert(e); // argument 0 is not a String instance
};


This is just the first basic example ... let's go to view something more interesting ?


// constructor example with
// 2 public methods and a private
// property
function MyConstructor(){
var property = "";

this.getProperty = function(){
return property;
};

// I need this method accept only String instances
this.setProperty = JavaStrict.call(function(value){
property += value;

// don't worry about internal scope (this referer)
alert(this.getProperty());
}, String);
};

// test them
var instance = new MyConstructor;
instance.setProperty("test");
instance.setProperty(new String(" me"));
try {
// this time I try to set an object
// that's not a String instance
instance.setProperty({});
}
catch(e) {
alert(e);
}


Seems interesting? That's another example, using public static returnValue method:

charToCode = JavaStrict.returnValue(
Number,
JavaStrict.call(
function(str){
return str.charCodeAt(0);
},
String
)
);

try {
alert(charToCode("a"));
}
catch(e) {
alert(e);
}

charToCode is a function that accept only String instances and returns a Number.
If You try to change function return usng, for example, a String or another type of instance, You'll view Error instead of char code.

If You want to create easyly strict type functions/methods You could use this shortcut too:
Strict = JavaStrict.call(function(returnValue, callback, arguments){
return JavaStrict.returnValue(returnValue, JavaStrict.apply(callback, arguments))
}, Function, Function, Array);

charToCode = Strict(Number, function(str){return str.charCodeAt(0)}, [String]);

Strict accepts a valid return type as first argument, callback as second and its arguments type as third parameter (that need to be an Array, as specified on Strict declaration).



apply and call difference
Both apply and call do the same thing but in a different way:

function concat(a, b){
return "".concat(a, b);
};

// after one of these lines concat will accept
// only String instances
concat = JavaStrict.call(concat, String, String);
// the same of ...
concat = JavaStrict.apply(concat, [String, String]);


If You want to add a String instance as return value, just use this line before or after call/apply one:

concat = JavaStrict.returnValue(String, concat);



How to accept or return every kind of instance?
JavaScript is not strongly typed (atleast not yet) and sometime a generic argument or returned parameter should be useful.
For these case You can specify, as expected argument/result, generic Object instance, that will accept null or undefined variables too.
However, if You use Object for every method, function or returned value, probably You don't need JavaStrict.


I hope this simple, tiny and packable function will be useful for your next JavaScript project!

5 comments:

Andrea Giammarchi said...

Anyone interesting? :/

However, I wonder if "null" values should be usefull to parse or not ... could anyone tell me what does He think "null" values should do?

kentaromiura said...

i think that null IS a object.
so null must be parsed like object.

Andrea Giammarchi said...

null is typeof "object" but isn't an instanceof Object.

An undeclared variable is not null but is undefined ... I need to shink about corect/expected behaviour with Void, "nullable" or undefined

Medyk said...

It's very interesting I didn't think that this would be possible..but I'm not sure is it practical - it can be very confusing. It's like changing language functionality.. no type hinting is part of javascript character and I think that it is better to go with it than against it.

Andrea Giammarchi said...

it can be very confusing
Strict Type that make code more confusing ?!? ... It's a bit nonsense :)


no type hinting is part of javascript character
That's why we often spend too much type to verify arguments or to debug code when some value is not the expected one.

That's why I created this function, that should help developers to create more debuggable and probably stable libraries.

The good thing is that when Yuo don't need Strict, You can just change Strict shortcut function, for example, returning dierctly the callback.

However just use it if You need them :D