My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, October 30, 2008

3, 2, ... 1, ... Coming Soon!

Guys, I can't wait for Ubuntu 8.10 and what's up in the website?
The countdown now shows a "Coming Soon" message ... I mean, a little news about when is that difficult?


I know there is a kernel problem since 27 October, and i hope you updated are updating the release to fix that problem with the 8.10 ... but shall you tell us more?
Kind Regards

And thank You :)

Tuesday, October 28, 2008

jQuery plug-in distributed elements via If, ElseIf, and Else

After a couple of instant and consecutive releases, I ended up with a plug-in that fits minified into 240 bytes :)

Here is the official plug-in page, while this is the example page and this is the summary:

;jQuery.fn.extend({
// Andrea Giammarchi - Mit Style Licence - V0.2
If:function(fn){
var __If__ = this.__If__ || this,
$ = __If__.filter(fn);
$.__If__ = __If__.filter(function(){return !~$.index(this)});
return $;
},
Else:function(){
return this.__If__;
},
Do:jQuery.fn.each
}); jQuery.fn.ElseIf = jQuery.fn.If;

Monday, October 27, 2008

jQuery If, ElseIf, and Else plugin

Update
Guys, I have to admit I created silly prototypes while all I need were much more simpler than I though :) Enjoy last version!
-------------------------------------

Try to imagine a page like this one:

<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</body>


.. and now try to imagine something like this:

function oddNumbers(){
// return true if element contain an odd number
return $(this).text() & 1;
};

$(function(){
$("div")
.If(function(){return $(this).text() == "3" || $(this).text() == "5"})
.text("match the 3 or 5 check")
.ElseIf(oddNumbers)
.text("odd numbers")
.ElseIf(function(){return $(this).text() == 2})
.Do(function(){ // if you need a closure ...
$(this).text("text is equal 2");
})
.ElseIf(function(){return $(this).text() == 6})
.text("match the 6 condition")
.Else()
.text("this is 4 or 8");
;
})


... now, try to imagine I created a plugin like this:


;jQuery.fn.extend({
// Andrea Giammarchi - Mit Style Licence - V0.1f
If:function(fn){
var $ = this.filter(fn);
$.__If__ = this.filter(function(){return !~$.index(this)});
return $;
},
ElseIf:function(fn){
var $ = this.__If__.filter(fn);
$.__If__ = this.__If__.filter(function(){return !~$.index(this)});
return $;
},
Else:function(){
return this.__If__;
},
Do:jQuery.fn.each
});


... and now try to enjoy it :D

Kind Regards

Thursday, October 23, 2008

Subclassing JavaScript Native String

Just a quick post about subclassing native String constructor.
All we need is to redefine valueOf and toString methods.

function $String(__value__){
this.length = (this.__value__ = __value__ || "").length;
};
with($String.prototype = new String)
toString = valueOf = function(){return this.__value__};

With incoming V8, TraceMonkey, Squirrelfish, and other (if any ...) advanced engines that transforms repeated code into machine one, performances wont be a problem anymore and everybdy could create its own implementation of the String.

Of course, these statements will be preserved:

var s = new $String("abc");
s instanceof String; // true
s.constructor === String; // true

while typeof will return an object but we can easily use another method such:

$String.prototype.type = function(){
return "string";
};

alert(typeof s); // object
alert(s && s.type()); // string

concat as other native methods willl work, but returned object, unfortunatly, wont be a $String.

Wednesday, October 22, 2008

Big Douglas begetObject revisited recycling a unique function

With the precedent post I realized I wrote a really tricky way to extend inline a function.Next code is the snippet summary:

MyExtendedConstructor.prototype = function(Function){
var callee = arguments.callee;
if(!(this instanceof callee)){
callee.prototype = Function.prototype;
return new callee;
}
}(MyBaseConstructor);

Above code uses the closure itself to create the intermediate constructor.
The reason i chose this way to operate that task was: why should I use another function when I already have one that is the closure itself?

Well done, one function instead of two ... but wait a second, why should I create a different function everytime instead of recycle a single one?

Douglas Crockford begetObject concept


In one of His historical posts, Big Douglas describes simple JavaScript inheritance and object cloning using an intermediate constructor. This is the Object.create function:

Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};

Above snippets is still used in I do not know how many JavaScript libraries or code over the net, to extends constructor prototypes or to create a clone of a generic object.

The snippet is clever, powerful, "perfect" for its purpose, but it creates many functions for each object and your JS engine, as your RAM, has not shields to prevent its aggressiveness when you use thousands of times that snippet.

This is a benchmark function example:

function bench(create){
for(var original = {test:"test"}, o = create(original), i = 0, time = new Date; i < 500000; i++)
o = create(o);
return new Date - time;
};

If we test above function with Douglas Object.create one, the result will be something like:

FireFox 3.0.3 - Intel Core2 6600 @ 2.40 - 2GB DDR2 RAM
------------------------------------------------------
Memory: 121.676 Kb
CPU: 50% (not responding)
Elapsed time: 1769 ms



Object.create revisited version


Next snippet is my revisited version of that function:

Object.create = function(Function){
// WebReflection Revision
return function(Object){
Function.prototype = Object;
return new Function;
}}(function(){});

these are advantages about recycling the function:

  • memory should not be increased, the function is one

  • execution speed should be faster, no functions created for each call

  • apparently, not a single behaviour different from the good old snippet


While these are results with the same configuration:

FireFox 3.0.3 - Intel Core2 6600 @ 2.40 - 2GB DDR2 RAM
------------------------------------------------------
Memory: 37.332 Kb
CPU: 35% (responding)
Elapsed time: 855 ms

Seems to be quite impressive, isn't it? Results are tremendously different with Internet Explorer, where the good old way lets the browser ask if it is the case to stop the script: thousands of milliseconds against approximately 1200 with my revision.

Not only to clone


I tested my revision to extend constructors as well, and everything seems to be absolutely fine. This is the function, based on the precedent one:

Function.extend = function(A, B){
A.prototype = Object.create(B.prototype);
A.prototype.constructor = A;
};

// Usage Example
Function.extend(MyExtendedConstructor, MyConstructor);


Why does it work?


Everything is about the clone strategy itself. When we clone an object, it does not matter that the original one is modified, the cloned will be an object a part.
Since the constructor used to create the clone is private, and since it is never modified by the function itself, it does not matter how many times we reassign its prototype, since the only important thing is when we create an instance with new keyword. That instance wont loose its inherited methods or properties.
As example:

function A(){};
A.prototype = {sayHello:function(){alert("Hello")}};
var a = new A;

// prototype redefinition
A.prototype = {};

alert(a instanceof A); // FALSE
a.sayHello(); // Hello

As I said, when variable a is created, it inherits everything from A.prototype and, of course, if A.prototype inherits from another constructor, the chain is respected and classic inheritance emulated. Using the unique function inside that closure, we are doing something like this:

function A(){}; // generic constructor

function Intermediate(){}; // intermediate function
Intermediate.prototype = {sayHello:function(){alert("Hello")}};

// assign the prototype creating an instance
// the instance does not loose its methods
// inherited during its constructor
A.prototype = new Intermediate;

var a = new A;

// we are changing the constructor prototype
// but A.prototype is an instance of the precedent one
Intermediate.prototype = {};

// the method is still there
a.sayHello();

// the prototype has not been changed
// when created it inherited precedent
// methods or variables
var b = new A;
b.sayHello();



Conclusion


In my opinion there aren't side effect but only performances and memory consumption improvements for every browser.
I do not know why I did not think about this way to recycle that function before, but for sure I will never use a new intermediate constructor again, unless somebody will post valid reasons to do it.
Finally, if everybody knew about this tricky way to recycle the constructor, I am sorry, I am late.

a new Relator object plus unshared private variables

This is a Robert Nyman's post dedicated reply, about JavaScript inheritance and alternatives and private variables.

First of all, I would like to say thanks to Robert for both interesting articles He is writing about JS inheritance, and a link to a personal comment which aim was to bring there my "old" documentation about classical JavaScript inheritance and usage of prototype, closures, and public, privileged, or private, scope when we create a constructor.

About


Last Rob's post talk about private variables, describing them as shared, if present outside the constructor, and valid only for singleton instances.
This is true, and could cause a lot of headache if we are not truly understanding closures and prototype shared methods behaviour, but there is a way to use this peculiarity about shared private variables to create dedicated private variables.

Before I will write about it, let's look into a generic shared private variable example:

Click = function(){
// closure for private methods / variables

// private shared variable
var _total = 0;

// returned constructor + prototype
function Click(){};
Click.prototype.add = function(){
_total++;
};
Click.prototype.getTotal = function(){
return _total;
};
return Click
}();

var left = new Click,
right = new Click;

left.add();
alert(right.getTotal()); // 1

Above example shows that if a variable is created outside the constructor and prototype shared methods use that variable, every call to one of those method from a generic instance will modify that single private variable, created once inside that closure. To obtain a private variable we need privileged methods:

Click = function(){ // privileged methods
var _total = 0;
this.add = function(){
_total++;
};
this.getTotal = function(){
return _total;
};
};

var left = new Click,
right = new Click;

left.add();
alert(right.getTotal()); // 0

As discussed before in my doc, in robert's posts, and everywhere else in the web, privileged methods create many functions for each instance, and with big projects this is not good for both memory and CPU usage.

new Relator object and unshared private variables


The Relator is an object capable to relate a generic variable with a clear object, without modifying the original variable.
The classic example is this:

var myNum = 123;
Relator.set(myNum).description = "I am number 123";
alert(myNum.description); // undefined
alert(Relator.get(myNum).description); // "I am number 123"

Since with Relator it is possible to create a unique relation between a generic object and a private Object, it was natural for me to think that a private variable could be a Relator like object using this as unique relationship.
The new version of my Relator still respect the precedent API, being a Relator itself, but is now able to return a new object Relator like that could be used, as example, inside a closure.

// new Relator can create a Relator like object with method "$"
PrivateRelator = function(Relator){
// Relator argument is a new Relator like object
// present only in this scope
return {
get:function(what){
var value = Relator.get(what);
return value && value.value;
},
set:function(what, value){
Relator.set(what).value = value;
}
}
}(Relator.$()); // create a new Relator

Relator.set(window).value = "Hello World";
Relator.get(window).value; // Hello world
PrivateRelator.get(window); // undefined
PrivateRelator.set(window, "Hello Private World");
PrivateRelator.get(window); // Hello Private World
Relator.get(window).value; // Hello World

The good part of Relator is that the stored variable, if it is an object, is stored by reference, and we can assign more than a private unique relationship between a single object and our extra informations.
The same pattern could be easily re-adapted to create a shared private variables:

Person = function(){

// private methods
function _getName(){
return _private.get(this).name
};
function _setName(name){
_private.get(this).name = name;
};

// private variable, shared by every function in this scope
var _private = Relator.$();

// constructor + prototype
function Person(){
// bridge to _private shared variable
_private.set(this);
};
Person.prototype.getName = function(){
return _getName.call(this);
};
Person.prototype.setName = function(name){
_setName.call(this, name);
};
return Person;

}();

// extended constructor
function Enhanced(){
// necessary to save
// this instance into _private variable
// accessible only via Person scope
Person.call(this);
};
(function(){ // quick runtime extend
var callee = arguments.callee;
if(this instanceof callee)return;
callee.prototype = Person.prototype;
Enhanced.prototype = new callee;
})();


var me = new Person(),
rob = new Enhanced();

me.setName("Andrea");
rob.setName("Robert");

alert([me.getName(), rob.getName()]);
// Andrea,Robert


Conclusion


Sometime a limitation could be easily managed to obtain desired result.
In this case, thanks to JavaScript closures and its prototype nature, the shared variable become a sort of bridge to obtain private variables for each instance.
It is important to understand that even if we extend the base constructor, every new instance will still persist into original _private variable, inside the Person scope, unless we do not specify a different one, redefining every method that use that variable as well:

(function(_private){
Enhanced = function(){
_private.set(this);
};
(function(){ // quick runtime extend
var callee = arguments.callee;
if(this instanceof callee)return;
callee.prototype = Person.prototype;
Enhanced.prototype = new callee;
})();
Enhanced.prototype.getName = function(){
return _private.get(this).name
};
Enhanced.prototype.setName = function(name){
_private.get(this).name = name;
};
})(Relator.$());


See you soon ;)

Wednesday, October 08, 2008

JavaScript bits and bops :-)

This post is about a couple of probably useful JavaScript functions, that on daily basis could make our code smarter ;)

String.prototype.Replace


Ok, ok, a prototype into a native constructor is not a good start point, but this one, strings dedicated, is probably one of those "must have" protos, a Replace with multiple inputs, as is for PHP.

String.prototype.Replace = function(replace){return function(RegExp, String){
if(!(RegExp instanceof Array))
RegExp = [RegExp];
if(!(String instanceof Array))
String = [String];
for(var result = this, i = 0, l = 0, index = RegExp.length, length = String.length; i < index; i++)
result = replace.call(result, RegExp[i], String[l < length ? l++ : l - 1]);
return result;
}}(String.prototype.replace);

With above prototype it is possible to search and replace with multiple RegExps and multiple replacements. The proto works as native replace one, but it is possible to perform a replace like this as well:

"abc".Replace([/a/, /b/, /c/], "d"); // ddd
"abc".Replace([/a/, /b/, /c/], ["c", "a", "b"]); // cab
"abc".Replace([/a/, /b/, /c/], ["d", function(){return "e"}]); // dee

Tricky enough?


A meanwhile function pattern


Sometime we need two arguments for a generic callback, but sometime we need to do something between the first argument and the second one.
A common generic example could be a time based callback, where we need to get a start time, to perform an operation, and then an end time.
With a simple pattern like this one:


function meanWhile(before, after){
if(2 < arguments.length)
after = arguments[arguments.length - 1];
// do stuff ... return other stuff
return after - before;
};

We are able to execute a couple of interesting operations.
A timing example is this one:

function bigLoop(){
for(var i = 0, max = arguments[0] || 1000000; i < max; i++);
};
meanWhile(new Date, bigLoop(), new Date); // 180 or less if your PC is faster
meanWhile(new Date, bigLoop(), bigLoop(), new Date); // 360 or less ...

Can you imagine better applications?

P.S. It's long time I do not post guys, sorry but it's really a busy period :)