looking for a full-immersion/face-to-face HTML5, JavaScript, and Mobile Web Development training in the heart of London? Book your spot
Showing posts with label function. Show all posts
Showing posts with label function. Show all posts

Thursday, March 08, 2012

I Heard You Like To Write Less

Update apparently this proposal is being considered in es-discuss ... not the implicit return so far but the "redundant" function keyword.
This is last draft from Brendan Eich:

FunctionDeclaration:
function Identifier ( FormalParameterList_opt ) { FunctionBody }
Identifier ( FormalParameterList_opt ) [no LineTerminator here] { FunctionBody }

ShortFunctionExpression:
Identifier_opt ( FormalParameterList_opt ) [no LineTerminator here] { FunctionBody }
Identifier_opt ( FormalParameterList_opt ) => InitialValue



I'm @qconlondon waiting for the next talk so I decided to take a couple of minutes to blog about this little experiment.
In ES-Discuss developers are still talking about function keyword, if it's needed or not.

I believe the fact CoffeeScript has no explicit function is one of the major reasons devs have been attracted so I made it even simpler.

Just Drop The Function

With current ES 3, 5, or 5.1 syntax I can't really see problems or ambiguity removing that keyword but if you find a case that could fail please let me know.
Of course if we use a keyword we should be able to understand the difference, i.e. with for, if, or others, and this simple test page is just an experiment: you write some code, you "functionize" it, and if the code does not run it's showed highlighted in red.
The RegExp is quite simple and straight forward and parsing time should never be a problem even for big projects.
The return is implicit, a bit Ruby style, but of course you can chose to return in the middle of a function.
Thing is, the very last statement will be returned and you can play with results.

I wonder if anyone would use such syntax on daily JavaScript coding. The parser needs improvements in any case so just think about it and let me know. Cheers

Tuesday, February 14, 2012

JSON.stringify Recursion + Max Execution Stack Exceeded

I believe this is a common problem, and we had a similar one today while debugging.
JSON methods do not support recursion ... which is the only thing I am really missing back to PHP serialize days.

Recursion Is Bad

Well, I would say cyclic references are never that good but sometimes these may happen and, specially while testing and debugging, it's more than useful to understand what happened there.
If you have cyclic/cross references in your code I suggest you to use approaches which aim is to avoid these kind of direct links.
Harmony Collections, specially Map and WeakMap, are indeed good helpers to reference indirectly objects without creating, hopefully, first level links and/or recursions.

How To Serialize Anyway

JSON.stringify() accepts a second argument called replacer.
I won't explain more than MDN about its potentials, but it can be really handy to avoid recursions.
A simple way to do it is indeed to store in a stack already parsed objects, included the object itself.
Some other extra operation may be handy too so the debug will be as complete as possible.

var replacer = function (stack, undefined, r, i) {
// a WebReflection hint to avoid recursion
return function replacer(key, value) {
// this happens only first iteration
// key is empty, and value is the object
if (key === "") {
// put the value in the stack
stack = [value];
// and reset the r
r = 0;
return value;
}
switch(typeof value) {
case "function":
// not allowed in JSON protocol
// let's return some info in any case
return "".concat(
"function ",
value.name || "anonymous",
"(",
Array(value.length + 1).join(",arg").slice(1),
"){}"
);
// is this a primitive value ?
case "boolean":
case "number":
case "string":
// primitives cannot have properties
// so these are safe to parse
return value;
default:
// only null does not need to be stored
// for all objects check recursion first
// hopefully 255 calls are enough ...
if (!value || !replacer.filter(value) || 255 < ++r) return undefined;
i = stack.indexOf(value);
// all objects not already parsed
if (i < 0) return stack.push(value) && value;
// all others are duplicated or cyclic
// mark them with index
return "*R" + i;
}
};
}();

// reusable to filter some undesired object
// as example HTML node
replacer.filter = function (value) {
// i.e. return !(value instanceof Node)
// to ignore nodes
return value;
};

A simple example about above function could be this one:

// how to test it
var o = {a:[], b:123, c:{}, e:function test(a,b){}};
o.d = o;
o.a.push(o);
o.c.o = o;
o.c.a = o.a;
o.c.c = o.c;
o.a.push(o.c);
alert(JSON.stringify(o, replacer));

Above alert will produce this kind of output:
{"a":["*R0",{"o":"*R0","a":"*R1","c":"*R2"}],"b":123,"c":"*R2","e":"function test(arg,arg){}","d":"*R0"}
which is surely not as bad as an exception, isn't it?

The Max Execution Stack Problem

Even using a stack variable, in order to avoid duplicated entries, the reason 255 < ++r is necessary is that the generic object may reference in one or more properties a DOM node.
Specially in big applications, the number of nodes, all unique, could be able to reach the function limit.
A tricky way to know this limit, which is browser and engine dependent, could be this one:

(function (Function, MAX_EXECUTION_STACK) {
if (MAX_EXECUTION_STACK in Function) return;
Function[MAX_EXECUTION_STACK] = function (i) {
try {
(function max(){
++i && max();
}());
} catch(o_O) {
return i;
}
}(0);
}(Function, "MAX_EXECUTION_STACK"));

// browser dependent
alert(Function.MAX_EXECUTION_STACK);

Unfortunately in the replacer we cannot use this number in any case because we don't know how many other times the function itself will be called but a good compromise, able to generate objects almost impossible to debug, would be Function.MAX_EXECUTION_STACK / 100 so the limit will scale accordingly.
In all other situations where we still have recursion and max execution stack problems but we are those calling our own function, this limit could be more than handy, i.e.

var
i = 0,
fn = function (obj) {
for (var key in obj) {
if (++i < Function.MAX_EXECUTION_STACK) {
parse(obj[key]);
fn(obj[key]);
}
}
}
;

... so now you know ...

Wednesday, January 04, 2012

Improving Function.prototype.bind

There are a couple of things I have never liked that much about Function#bind and this post is about proposing a pattern hopefully better than common one.

At The End Of The Function

A common argument about parentheses around inline invoked functions is that developers can easily recognize them.

// considered ambiguous
var someThing = function () {
return {};
}();

// considered not ambiguous
var someThing = (function () { // note the parenthesis
return {};
}()); // note the parenthesis

// exact same behavior of latest one
// but considered slightly ambiguous
var someThing = (function () { // note the parenthesis
return {};
})(); // note the parenthesis

The parentheses version apparently wins but, specially when no assignment is needed, I believe these are even less ambiguous:

-function(){
alert("OK");
}();

+function(){
alert("OK");
}();

!function(){
alert("OK");
}();

Of course if there is an operator that function will be executed, why on earth anyone would do that otherwise?
Anyway, the problem with all of these human friendly syntax pattern recognition strategies, is that the context of the function, or the whole code behavior, could be polluted/changed via bind or call or apply so we need in any case to scroll 'till the end to better understand what is going on inside the function and what is returned, exactly.

// ES3 example
var something = (function(){
// this could be global object or something else
return this.doSomeStuff();
}.bind(unexpectedObject)); // or call for other cases

// ES5
var something = (function(){"use strict";
// if there is a this reference
// we need to reach the end to understand
// what is it
return this.doSomeStuff();
}.bind(unexpectedObject));

The summary is that bind, used inline, is more like a yoda condition rather than a developer friendly helper so the first point is that bind, as it is, forces the developer to always check the end of the function to know if this has been executed inline or it has been bound to a different context, as well as yoda conditions forces the developer to read "upside down" a statement.
Last, but not least, of course if it's just about bind, parentheses are not helping at all ... still scroll 'till the end

// perfectly valid, not even executed
// but still important to know
// what will be the context for future calls
var something = function(){
return this.doSomeStuff();
}.bind(unexpectedObject);


Team Speaking

Ok, agreed, a function bigger than 10 lines is not that good and should be split and blah blah blah ... point is that sometimes function have to be big since these provide us a way to create private variables and methods ... ok?
Also if that was "the good part", I mean just putting parentheses around, there is some conflict with the fact that functions should not be that long ... I mean, how can we mistake whatever happened in 10 lines?
The truly good part could be done by developers, specially those that work in a team.
The first good rule is to write a bloody single line comment at the very first line, this would just solve everything:

var something = function () {
//! executed inline, returns object

... the rest of the code ...
}();

var somethingElse = function () {
//! bound to variable obj

... the rest of the code ...
}.bind(obj);

var somethingCrazy = function () {
//! bound to obj + executed inline

.. the rest of the code ...
}.bind(obj)();

-function(){
// bound to obj
}.bind(obj)();

Got it? Nobody would ever complain about these little helps ... isn't it? But since we are all lazy devs, the second helper is function declaration rather than function expression.

function impossibruToConfuse(){}

var something = impossibruToConfuse.bind(obj);
var something = impossibruToConfuse();
var something = impossibruToConfuse.call(obj);

With a single line to read I believe the problem is solved ... isn't it? Still ways to improve.

Unable To Retrieve Same Bound Function

The second most annoying thing ever, something that leads inevitably to uncomfortable patterns, is the inability to retrieve an already bound function through the same object.
In my humble opinion, was a freaking design mistake indeed to create a new bound object per each bind call since I believe nobody in this world ever used this "feature".

function task(){}

// Y U NO THE SAME !!!
task.bind(window) === task.bind(window);
// false ....

If the function is the same it means it has same context, inner and outer scope of the other function bound to the same object.
If we bind twice the same object we are doing it wrong 'cause most likely we never meant/need two different bound callbacks/objects for that task ... isn't it?

An Error Prone Logic

The most basic fail of this logic is about listeners, both DOM listeners or self implemented listeners, extremely common in an always more asynchronous driven language as JavaScript is.

generic.addEventListener("stuff", stuff.bind(obj), false);

// how many times have you seen this later on?
generic.removeEventListener("stuff", stuff.bind(obj), false);

Above example won't work as expected ... of course it won't work as expected ... developers expect the same function/object, instead they have a new one.
This approach forces developers to store temporarily the bloody bound function to some private, global, variable or property.

obj._boundStuff = stuff.bind(obj);
generic.addEventListener("stuff", obj._boundStuff, false);

// ... later on ...
if (obj._boundStuff) {
generic.removeEventListener("stuff", obj._boundStuff, false);
}

Remember how lazy we are so that parentheses became one of the good parts of JavaScript since a line of comment was too boring? Now look again at latest example and think how many times you have done something similar ...

A Clever Object.prototype.boundTo

With ES5 we are so lucky to be able to pollute global constructors without influencing for/in and as long as our implementation is not obtrusive and, most important, makes sense.
I came up with this proposal in order to solve at least latest problems described before: a lazy boundTo method

!function (Object) {

// (C) WebReflection - Mit Style License

var // private scope shortcuts
BOUND_TO = "boundTo", // or maybe "asContextOf" ?
defineProperty = Object.defineProperty,
bind = defineProperty.bind || function (self) {
// simple partial shim for "not there yet" ES5 browsers
var callback = this;
return function bound() {
return callback.apply(self, arguments);
};
}
;

defineProperty(
Object.prototype,
BOUND_TO, {
value: function (callback, remove) {
// only the very first time
// two private stacks are created
// and related to the current object
var
cbStack = [],
boundStack = [],
self = this
;
// overwrite the inherited BOUND_TO method
// with the one we actually need
defineProperty(
self,
BOUND_TO, {
value: function boundTo(callback, remove) {
var
i = cbStack.indexOf(callback),
callback = i < 0 ?
boundStack[
i = cbStack.push(callback) - 1
] = bind.call(callback, self)
:
boundStack[i]
;
// falsy values accepted
// except null or undefined
// so it's true by default
if (remove == false) {
cbStack.splice(i, 1);
boundStack.splice(i, 1);
}
// returns bound callback in any case
// handy to remove listeners and clean stacks
// in one single operation
return callback;
}
}
);
// only the first time, invoe the overwritten method
// use directly latter one every other time
return self[BOUND_TO](callback, remove);
}
}
);
}(Object);

How above snippet is supposed to be used? Here a basic example:

generic.addEventListener("stuff", obj.boundTo(stuff), false);

// ... later on ...
generic.removeEventListener("stuff", obj.boundTo(stuff, 0), false);

// bear in mind that ...
obj.boundTo(stuff) === obj.boundTo(stuff);
// always ... unless we release explicitly the bound function/object
obj.boundTo(stuff, false) !== obj.boundTo(stuff);
// since once removed, the new obj.boundTo call will create a new one

Pros

No need to check, no need to store the bound version, memory leaks safe, no need to do anything extra except calling the method through, and this is needed, the same function.
The semantic is straight forward and rather than a yoda condition we have a clear operation that means: return the function created to bind this object as context.
Last, but not least, even if the function was not bound, everything should work as expected, as long as the removeListener generic method has been implemented properly ( checking if the callback/object was attached already )

Cons

Not really, but the function has to be the same. It must be said that two apparently identical functions could be just a copy and paste in two completely different outer scopes. This means that there is no bullet proof way to understand if a function written twice is similar to another one since it is not possible to understand surrounding scopes and it would be silly to do this even on the JS engine level. I am talking about another, unfortunately, common mistake:

// wrong examples ... does not work as expected

generic.addListener("whatever", function () {
return this.whatever;
}.bind(object), false);

// followed by ...
generic.removeListener("whatever", function () {
return this.whatever;
}.bind(object), false);

// or in this proposal case ...

generic.addListener("whatever", object.boundTo(function () {
return this.whatever;
}), false);

// followed by ...
generic.removeListener("whatever", object.boundTo(function () {
return this.whatever;
}), false);

// ... but this is not how JavaScript works ...

Memory speaking, the very first time we use this strategy we create two extra arrays able to speed up operations through indexed function and and bound version per each object. This is inevitable in any case and it's almost exactly the same we do when we address once the bound function.
Once the object has been Garbage Collected, related private arrays will have a reference count equal to zero so the memory should clean up automatically without problems and including all functions bound to that object.

As explained in the example, it is possible in any case to release explicitly bound functions so we can feel like the memory usage is under control.

Why No Arguments

The combination of arguments could be such big number that this technique won't be interesting anymore, specially regarding performances.
It does not really make sense to over complicate such basic, most needed, scenario but if you think this is the biggest impediment, then the name should simply be asContextOf so that no ambiguity would be shared with bind native signature.

Update - Preserving Private Methods

Another reason to chose my proposal is the ability to bind proper private methods without using the current instance to store the bound method anywhere ... follow the es-discuss ML to know more but here the stupid, basic, proof of concept:

// stupid useless example ... just as concept
var Counter = (function () {
// private
function increase() {
this.clicks++;
}

function Counter() {
// none out there should be able to retrieve the bound function
document.addEventListener("click", this.boundTo(increase), false);
};
Counter.prototype.clicks = 0;
Counter.prototype.destroy = function () {
// so that only this class scope can control things and nobody else
document.removeEventListener("click", this.boundTo(increase), false);
};
return Counter;
}());


As Summary

I am pretty sure this simple lazy created proposal would be ideal for many frameworks and projects but if I am missing something or if you have any improvement to suggest, I will be more than happy to listen to you.
Enjoy simplicity over semantic, this is yet another KISS and YAGNI proposal from this blog.

Tuesday, November 08, 2011

Function.prototype.notifier

There are way too many ways to stub functions or methods, but at the end of the day all we want to know is always the same:
  • has that function been invoked ?
  • has that function received the expected context ?
  • which argument has been passed to that function ?
  • what was the output of the function ?

Update thanks to @bga_ hint about the output property in after notification, it made perfect sense

The Concept

For fun and no profit I have created a prototype which aim is to bring a DOM like interface to any sort of function or method in order to monitor its lifecycle:
  • the "before" event, able to preventDefault() and avoid the original function call at all
  • the "after" event, in order to understand if the function did those expected changes to the environment or to a generic input object, or simply to analyze the output of the previous call
  • the "error" event, in case we want to be notified if something went wrong during function execution
  • the "handlererror" event, just in case we are the cause of an error while we are monitoring the original function
The reason I have chosen an addEventListener like interface, called in this case addListener, is simple: JavaScript works pretty well with event driven applications so what else could be better than an event driven approach?

Basic Example


var nFromCharcode = String.fromCharCode.notifier({
before: function (e) {
if (e.arguments.length > 2048) {
throw "too many arguments";
e.preventDefault(); // won't even try to execute it
}
// in case you want to remove this listener ...
e.notifier.removeListener("before", e.handler);
},
after: function (e) {
if (e.output !== "PQR") {
throw "expected PQR got " + e.output + " instead";
}
},
handlererror: function (e) {
testFramework.failBecause("" + e.error);
}
});

// run the test ...
nFromCharcode(80, 81, 82); // "PQR"
nFromCharcode.apply(null, arrayOf2049Codes); // testFramework will fail

The notifier itself is a function, precisely the original function wrapper with enriched API in order to monitor almost every aspect of a method or a function.
The event object passed through each listener has these properties:
  • notifier: the object create to monitor the function and notify all listeners
  • handler: the current handler to make the notifier remove listener easier
  • callback: the original function that has been wrapped by the notifier
  • type: the event type such before, error, after, handlererror
  • arguments: passed arguments transformed already into array
  • context: the "this" reference used as callback context
  • error: the optional error object for events error and handlererror
  • preventDefault: the method able to avoid function execution if called in the before listener
  • output: assigned only during "after" notification and if no error occurred, handy to compare expected results

I guess there is really nothing else we could possibly know about a notifier, and its callback, lifecycle, what do you think?

The Code




As Summary


I have also a full test coverage for this notifier and I hope someone will use it and will come back to provide some feedback, cheers!

Sunday, October 09, 2011

Taking The Bat-Formula To The Next Level

When you wake up on Sunday morning with upside-down stomach and batcode in mind, you may realize it's time to rest a bit.

with (/*Bat*/Math) Array(16).join(
pow(/*JOK*/E/*R*/, cos, E/*vil*/)
) + "batman";

The output is the same produced by the original bat-formula:

'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNbatman'

Have a nice Sunday.

Wednesday, October 05, 2011

bind, apply, and call trap

quick one out of ECMAScript ml

var
// used to trap function calls via bind
invoke = Function.call,
// normal use cases
bind = invoke.bind(invoke.bind),
apply = bind(invoke, invoke.apply),
call = bind(invoke, invoke)
;


What Is It

This is a way to trap native functions method in a handy way. Used in a private scope, it can address these methods once so that we can rely nobody can possibly change them out there for some script injection and only if we are sure the script has been loaded at the very beginning.

How To Use Them

Here few examples:

// secure hasOwnProperty
var hasOwnProperty = bind(invoke, {}.hasOwnProperty);
// later on
hasOwnProperty({key:1}, "key"); // true
hasOwnProperty({}, "key"); // false

// direct slice
var slice = bind(invoke, [].slice);
slice([1,2,3], 1); // 2,3
slice(arguments); // array

// direct call
call([].slice, [1,2,3], 1); // 2,3
// direct apply
apply([].slice, [1,2,3], [1]); // 2,3

// bound method
var o = {name:"WebReflection"};
o.getName = bind(
// the generic method
function () {
return this.name;
},
// the object
o
);
o.getName(); // WebReflection
That's pretty much it, except if we don't trust native Function.prototype, we should not trust anything else as well so maybe it's good to use these shortcuts just because they are handy ;)

Tuesday, March 16, 2010

Anonymous Style

When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.

I have already commented the popular JavaScript Code Convention article, but latest cited sentence is probably the only one I have never been sure about.

Why Bother

Actually, I have always found the expression:

var something = function(){

// do stuff
// return something

}(); // invoke
kinda enough to invoke inline a function expression.
Somebody argued that above style is ambiguous.
Since an inline invoke could be performed against a massive function body, the point is that we may need to scroll 'till the end of the function expression to know if it has been executed or not.
In my opinion, whenever there is a function expression, we should always check the end of this function or we'll never be sure about the assigned value.
Fair enough, even if the function could not be necessary invoked:

var something = function(){

// do stuff
// return or not

}.bind(this);
expressions are usually wrapped in any case regardless what's up at the end.

Still ... Why Bother

The most common implementation of this code convention we can find almost everywhere, included my shared code, is this one:

var something = (function(){

// do stuff
// return something

})(); // invoke

What is actually wrong with this implementation?
Let's simply imagine the function returns a function:

var something = (function(){
return function(){
return 123;
};
})();

Now, let's imagine that we would like to execute runtime the returned function, since we know that expression will return one:

var something = (function(){
return function(){
return 123;
};
})()(); // <= WTF?

I am pretty sure that ()() at the end of a runtime invoked expression, will bring us back to origins, where "we had to check 'till the end of the function", at least to understand what is going on ...
In few words, and as I have said, the scroll 'till the end of whatever function should be mandatory, if the code is not our one, and we would like to understand what this code actually does.

Non Ambiguously Speaking

If we follow Mr D. suggestion, we could say that this strategy will be rarely ambiguous.
To spot a wrap is definitively more easy than spot a potential typo, as 4 brackets could suggest:

var something = (function(){
return function(){
return 123;
};
}());
With latter snippet we can certainly say with a quick look that something refers the value returned by the invoked expression. It's wrapped, it must be an invoke rather than a function assignment, and it could be whatever value.
The instant we add other brackets, we are obviously dealing with the returned value:

var something = (function(){
return function(){
return 123;
};
}())(); // invoke the returned value

In other words we are able to split the inline invoked expression, with the rest of the logic, but still scrolling through the end!


Moreover

The usage of brackets makes the assignment superfluous:

// first case analyzed without brackets
(function(){

// do stuff

}());
In this case we are clearly creating a closure to avoid global space pollution and to perform some useful operation.
Since this is basically what we can find almost everywhere in many different libraries or piece of libraries, and since we have some shortcut to instantly reach the end of a file, why should we put the inline invoke outside the operation?

// first case analyzed without brackets
(function(){

// do stuff

})();
The sequence of )() could suggest that something happened before and somehow it constrict us to check if there are other 2 round brackets before those spotted at the end.
Furthermore, if we have an expression this is what we could write:

var something;

// other code

(something = function(){

// do stuff

})();
Again, unless we did mean that operation, maybe to avoid IE problems with named function expressions, those brackets outside the "wrap" could truly be considered ambiguous: was I trying to assign the expression result or the function itself?

something = (function(){

// do stuff
// return stuff

}());
There we have again a clear statement of what we were planning to do, isn't it?

Anonymous Assignment

We could think about some common pattern we can consider less error prone, and less ambiguous ... the first one is the classic assignment, performed for prototype properties, to avoid IE problems, or simply assign callbacks:

something = function(){};


Inline Invoke

We may agree that next one is the bets way to make an inline invoke non ambiguous:

something = (function(){}());

Same is if we are not returning anything, so that the expression will be called simply because we need a closure:

(function(){}());


Inline Constructor

This is not truly such common technique, but there is a massive difference if we use brackets or not.

var a = new (function(){
return Array;
}());
// true
alert(a instanceof Array);


var a = new function(){
return Array;
}();
// false
alert(a instanceof Array);
// a is actually the Array constructor
alert(a === Array);

The usage of new before an expression is something more suitable for ternary operator:

var o = new (typeof null !== "object" ? Object : String);

not particularly suitable for inline constructor concept.
This simply means, in my opinion, that if we meant to use the function as a Singleton, we should never put brackets around:

var Singleton = new function () {
var secret = "Singleton Baby!";
this.constructor = Object;
this.toString = function () {
return secret;
};
};

alert(Singleton);
// Singleton Baby!


As Summary

Earlier, I found the initial advice kinda redundant or superfluous, but I must admit it could make sense specially in weird cases, and this is why I have personally started to adopt it without feeling less readable at all.
Is there any other case where we could try to avoid expression ambiguity?

Saturday, February 20, 2010

Function.prototype.bind

Quick post about a fast Function.prototype.bind implementation.

Function.prototype.bind


function bind(context:Object[, arg1, ..., argN]):Function {
return a callback able to execute this function
passing context as reference via this
}

In few words, if we have a generic object, we don't necessary need to attach a function to create a method:

// a generic function
function name(name) {
if (name == null) return this.name;
this.name = name;
return this;
}

// a generic object
var wr = {name:"WebReflection"};

// a callback with a "trapped" object
var fn = name.bind(wr);

alert([

// wr has not been affected
wr.name, // WebReflection

// fn can always be called
fn(), // WebReflection

fn("test") === wr, // true
fn(), // test
wr.name // test

].join("\n"));

Designed to ensure the same context whatever way we decide to use the callback, included call, apply, setTimeout, DOM events, etc, Function.prototype.bind is one of the most useful/powerful JavaScript concept.
Unfortunately, this will be standard only with newer browser ...

Optimized bind for every browser


Update: as I have said I code what I need, I rarely google for simple tasks like this. Most of this code, in any case, has been readapted and tested to reach best performances, based on this proposal.

if (Function.prototype.bind == null) {

Function.prototype.bind = (function (slice){

// (C) WebReflection - Mit Style License
function bind(context) {

var self = this; // "trapped" function reference

// only if there is more than an argument
// we are interested into more complex operations
// this will speed up common bind creation
// avoiding useless slices over arguments
if (1 < arguments.length) {
// extra arguments to send by default
var $arguments = slice.call(arguments, 1);
return function () {
return self.apply(
context,
// thanks @kangax for this suggestion
arguments.length ?
// concat arguments with those received
$arguments.concat(slice.call(arguments)) :
// send just arguments, no concat, no slice
$arguments
);
};
}
// optimized callback
return function () {
// speed up when function is called without arguments
return arguments.length ? self.apply(context, arguments) : self.call(context);
};
}

// the named function
return bind;

}(Array.prototype.slice));
}


Why Bother

The concatenation optimization is something rarely present in whatever framework/library I have seen. While it makes the code a bit bigger than usual, performances will be the best for most common cases, those where optional arguments are not passed at all.
A simple test case, one of my favorites, able to solve the classic IE problem with extra arguments passed to setInterval/Timeout:

(function(){

var callback = function(time){
if (1000 < new Date - time)
return alert("1 second with a default argument");
setTimeout(callback, 15);
}.bind(null, new Date);

setTimeout(callback, 15);

}());

Monday, January 18, 2010

Good Old And Common JavaScript Errors

... I won't write any introduction, but I'll let you comment, OK?

for loops (plus ++i)



for(i = 0; i < 10; i++){}
// global i defined

for(var i = 0; i < something.length; i++){}
// cache the length if it won't change during the loop
// associate once only under certain conditions to speed up

for(var i = 0; i < 10; ++i) {}
// there is absolutely nothing wrong in above loop

Few people told me something like: "doode, if you use ++i at the end you need to write i < 11 'cause i will be 1 inside the loop" ... basically the for loop has been rarely understood, let me try again:

// directly from C language, 1972
for(

// optional inline declaration, coma accepted for more vars
;

// optional condition to verify
// if undefined, it loops until a break is encountered
// this condition is performed BEFORE the first loop
// if false, the loop will never be executed
;

// optional POST operation, it will never be executed
// if the condition is false, "", 0, or null
// it is executed in any case AFTER the loop, if any
){};


// example
for(var i = 0; i < 1; ++i){
// one single execution
// i will be 0 here
};
// i will be 1 here

The reason ++i is preferred over i++, whatever Google go language decided about it, is that i++ and ++i are totally different and you need to understand when, or why, you need i++ or ++i.
While ++i increments directly the variable, returning the variable itself, if numeric, i++ returns a NEW variable with the precedent value AND it increments the i var as well.
Pure JavaScript Example

function Num(value) {
this.value = value;
};
Num.prototype.valueOf = function () {
return new Num(this.value);
};
Num.prototype.toString = function () {
return "" + this.value;
};

var a = new Num(0);
var b = a++;
alert(a); // 1
alert(b); // 0
alert(a == b); // false

// again

var a = new Num(0);
var b = ++a;
alert(a); // 1
alert(b); // 1
alert(a == b); // true

It does not matter if speed speaking, the difference is "not that consistent", it matters that we are programmer, and if two things mean different things, we want to understand them, am I wrong?

Already defined variables, and scopes


Another piece of code you can find around the net, is this:

// something defined globally
var num = 1;

(function () {
// try to set a default
var num = num || 0;
})();

Above code will never work, and it's the ABC about scope and functions.
It's exactly like this:

// something defined globally
var num = 1;

(function (num) {
// now try to find the global num without this. or window. ...
})();

Same is for arguments:

function A() {
// this is actually correct since arguments shares same scope
// no shadowing in this case, thanks to qfox
var arguments = arguments || [];
};

What we need to understand, is that next code is ALWAYS true:

var u = 123;
(function () {
var u = (typeof u === "undefined");
// u is TRUE!!!
})();

The moment we define a scoped variable, it has precedence over whatever outer scope: bear in mind!!!

new Array, new Object


I can't wait the day people will stop to prefer this code:

var a = new Array(); // NOTE: no length/elements specified
var o = new Object(); // NOTE: no object to wrap/convert

rather than:

var a = [];
var o = {};

There are no excuses at all. First of all, the "new Array/Object" way is unsafe, since both constructors can be easily redefined/wrapped, as explained ages ago in many different security related JavaScript issues.
Moreover, we have both more bytes to digest and reduced performance, and a compiler/minifier that is so cool that will change automatically new Array into [] will simply potentially break our code so we cannot even rely improvements with production code.
So ... PLEASE DON'T!

... and new Function ...

Hey, Java guys, please answer this question:
Would you ever use in your Java life a factory method via "new" ???
Seriously, I don't get it ... let's go one step back ...

The Meaning of Factory


The essence of the Factory Pattern is to "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."


JavaScript Functions Behavior

If a JavaScript function returns a primitive value such: "string", true, false, null, int, double, new function will return an instanceof that function, overriding the returned result.
Same is for no returns, or return undefined.
If a JavaScript function returns an object, the usage of new is completely redundant and useless.

Array, Function, Object, and RegExp are Factory!!!



var a = Array();
var b = new Array();
var c = [];
[
a instanceof Array,
b instanceof Array,
c instanceof Array
]; // true,true,true


Boolean, Date, Number, and String are both primitive casts and Object constructors!!!



var a = 1;
var b = Number("1");
var o = new Number(1);
a === b; // true
a === o; // false
a == o; // true
a instanceof Number; // false
o instanceof Number; // true
typeof a; // number
typeof o; // object

As summary, and again, please repeat with me:
If a JavaScript function returns a primitive value such: "string", true, false, null, int, double, new function will return an instanceof that function, overriding the returned result.
If a JavaScript function returns an object, the usage of new is completely redundant and useless.


new Class(whatever) === new Factory(whatever)!!!


This is the most misunderstood part that seems so logical but does not make sense at all. 99.9% of cases and in different libraries we can find the classic call to new Class to create what people think is a Class in JavaScript (in few words, to populate the prototype of a runtime created function).
Wait a second ... did I just say: to create a Class?
Uhm ... so, we don't create an instance ... we create a class ... uhm again, so, we are using a Factory, isn't it? :zizi:

Function.createClass() would be hundreds of times more correct, logically speaking, but we all like the new Class, right?
Well, I wonder how many Java Gurus create they Java classes via new Class() on daily basis ... what? You have to define a class, not to create one? ... oh, REALLY???
MooTools use new Class to create runtime functions, parse the configuration object in order to populate the created function prototype, extending it with a completely useless this, that could be simply Class.prototype without useless runtime instanc`es creation for each Class, to finally return a function that is not instanceof Class ... not even primitives values in JavaScript are that ambiguous, isn't it?

new Class({}) instanceof Class; // FALSE!!!

MooTools is simply one in the ocean of libraries that use this misconception to create Functions, not Class, Function.
Considering that JavaScript has no classes, something apparently unacceptable for GWT and friends maniacs that absolutely need to compile their Java application inevitably into a prototypal based programming language as JavaScript is, thinking they have more power over the application, I agree that classic OOP is something so intrinsic in the IT panorama, that it will never die and it could make somehow things simpler for newcomers into JavaScript. OK, I am with you ... can we at least agree about the fact new factoryMethod does not make sense at all?

Logically Speaking ...


Rather than nonsense why don't we simply respect JavaScript native behavior?
If we consider native constructors behaviors such Boolean, Number, or String, I have already described what's up if we use new or not.
There is a massive difference between new and not new ... so why don't use the same behavior for Funciton?

// example
var f = Function("return 'function'");
alert([f instanceof Function, f()]);
// true,function

var f = new Function({toString:function(){return "instance"}});
alert([f instanceof Function, new f()]);
// true,instance

In few words we can easily think about Function as a primitive function creator AND as a function instances creator, those that we'll love to use to instantiate our application objects. Does it sound really that silly?

var Function = (function (Function) {
// (C) WebReflection Mit Style

// Class with private constructor
function constructor(constructor) {
function Class() {
constructor.apply(this, arguments);
};
return Class;
};

// Class creator
function Class(__proto__) {
function Class() {};
if (__proto__) {
if (hasOwnProperty.call(__proto__, "constructor")) {
Class = constructor(__proto__.constructor);
};
(Class.prototype = clone(__proto__)).constructor = Class;
};
return Class;
};

// special Function
function $Function(arguments, body) {
return this instanceof Function ?
Class(arguments) :
body == null ? Function(arguments) : Function(arguments, body)
;
};

// private variables
var
hasOwnProperty = Object.prototype.hasOwnProperty,
clone = Object.clone || (function () {
function clone() {};
return function (__proto__) {
clone.prototype = __proto__;
return new clone;
};
})()
;

// public static explicit factory
$Function.create = Function;
$Function.createClass = Class;

$Function.prototype = Function.prototype;

return $Function;
})(Function);

Here we are, and the best thing is that we can extend the prototype chain simply passing another prototype as configuration object.

function A(){};

var B = new Function(A.prototype);

alert(new B instanceof A); // true

Moreover, since whatever library will use a Function to create other functions, but since most of the time the new Class won't return an instanceof Class, with my suggestion whatever created "Class" will simply inherit Function.prototype.methods OR, if we want to add custom public methods, we can always do it later.
Finally, with a simple closure, we can still be semantic, and define private methods:

var MyClass = new Function((function () {
function set(value) {
this.value = value;
};
return {
constructor:function (value) {set.call(this, value)},
get:function () {return this.value}
};
})());

var o = new MyClass(123);
alert(o.get()); // 123

Now it's your turn, feel free to comment the path I followed, and give me other suggestions/common errors, if you remember any ;)

Update I almost forgot one of the most famous/silly one ...

Arrays "for in"



var a = [];
a[1] = 1;
a[0] = 0;

// global key defined
for(key in a);

// key will be first 1, then zero, in Internet Explorer and Opera
for(var key in a);

Another common mistake is to think that "for in" is good for arrays.
First of all the iteration order is unpredictable, there is no rule about "for in" iteration (or if any, nothing that is standard, cross-browser speaking) plus it's way slower than a normal iteration via length. Please DON'T!!! In this case as well.

Monday, October 12, 2009

Named function expressions demystified III

Update For those interested about Internet Explorer scope resolution, I summarized everything in 5 slides.


This is hopefully the end of the Named function expressions demystified trilogy, where here you can find episode I, and episode II.
Juriy knows I am hard to convince, but apparently he is not better than me at all ...

Inglorious Correction

Sure, it's better than nothing, but after I have spent dunno how many tweets plus 2 posts, all I have obtained is a small correction in the whole article (and you have to scroll a bit before):

Generally, we can emulate function statements behavior from the previous example with this standards-compliant (and unfortunately, more verbose) code:

var foo;
if (true) {
foo = function foo(){ return 1; };
}
else {
foo = function foo() { return 2; };
};

// call the function, easy?
foo();


Above snippet is the best solution in the entire article but probably to avoid my name in article credits, and it does not matter since I have already said it's not about the copyright, and surely to avoid personal ego conflicts, the suggested one is a surrogate of above snippet, quite embarrassing from a developer point of view, isn't it?

var f; // create an alias, WHY!!!!!!!!!
if (true) {
f = function foo(){ return 1; };
}
else {
f = function foo() { return 2; };
};

// create a reference in order to remove a reference, WHY!!!!!!!!!!!
var foo = null;

// call the function via another alias, WHY!!!!!!!!!!!
f();

Above snippet is just a surrogate because the first one simply create an alias which will refer the proper function. Let's be simply developers avoiding obtuseness, OK?

Re Solution Pros

  1. it's standard, no excuses at all!
  2. variables on top, no way we can forget to nullify the function and we don't need to create a reference which aim is to remove a reference, cause the reference is already assigned, no memory problems at all (possibly less, since there is nothing referenced to a null value)
  3. semantic, we can easily refer to the function, since the whole point is to solve the missed arguments.callee plus IE inconsistency ...
  4. standard again, because it perfectly emulates ECMAScript 3rd Edition behavior even in Internet Explorer
  5. the day we will need to nullify the function will be the day we meant it, and not a surpassed convention


Why My Re Solution Is More Standard

This is the expected behavior in all browsers, except Internet Exlorer and Opera, via Internet Explorer emulation:

var f; // let's use the suggested alias
// for demonstration purpose
if (true) {
f = function foo(){
// this is LOGICAL
// but in IE it will be false
// because foo will be the
// the other one, even if that
// else will never be executed!
alert(foo == arguments.callee)
};
}
else {
// IE will declare this function
// in any case since there is NO DIFFERENCE
// between expression and declaration
f = function foo() { return 2; };
};

f();

With my Re Solution the behavior is the expected one, alert(foo == arguments.callee) will be true in every browser ... do you still have doubts?

Re Solution Cons

  1. unfortunately, more verbose
This must be a joke ... more verbose? First of all we are dealing with developers that don't care at all about verbosity. Kangax as everybody else in credits always preferred verbosity since minifier and compressor could take care about this verbosity recreating, and I love the irony of this part, exactly the suggested case.

Re Solution Pros II

  1. being the function name declared on the top of the function, as I have said a well known good practice, every IDE will automatically suggest that name as soon as we'll startt to type it: does verbosity matter?
  2. As we all know gzip and deflate compresses repeated words more efficiently, as result the Re Solution is even smaller if we don't munge it, does verbosity matter?


Re Solution Is More Logical And Smaller

Here the simple test everybody can do. Two pages, same code, except the first one is Re Solution, 99 bytes, while the second one is Juriy suggestion, 111 bytes.

<?php ob_start('ob_gzhandler'); ?>
var foo;
if (true) {
foo = function foo(){ return 1; };
}
else {
foo = function foo() { return 2; };
};


<?php ob_start('ob_gzhandler'); ?>
var f;
if (true) {
f = function foo(){ return 1; };
}
else {
f = function foo() { return 2; };
};
var foo = null;

Do we have a single valid reason to use the Juriy suggestion over mine? I would honestly feel an idiot preferring the second one, since few bytes and more logic (foo is the function foo) against spread variables declarations (top and the middle with F = null) via aliases rather than function names inside the function itself where a debugger will show the name but we have to remember the alias, plus the possibility we forget to nullify the reference consuming more memory ... I mean, this is not the first of April, isn't it?

And That's Not All Folks

We are developers, not monkey, I always dislike generic affirmations a la eval is evil, the most used function since Ajax epoch, obviously included in json2.js itself, since is natural and logical to use it when necessary. Juriy corrected his article to underline how unprofessional am I suggesting a last option for IE behavior ... well, probably he has never thought about ternary assignment, isn't it?
// Never do this!, that's what I can read at some point, but we should think carefully before these statements.
Here there is an example where the function will be a named one but there are no differences in this case for IE, indeed the last option is the IE one.

// somewhere in a closure ...
// (otherwise add will be public in IE,
// but I hope we went further than this
// at this point and after 3 posts
// plus an entire article ...)
var event = {
add:document.addEventListener?
function add(){
alert([add, document.addEventListener]);
}:
function add(){
alert([add, document.attachEvent]);
}
,
del:document.removeEventListener?
function del(){
alert([del, document.removeEventListener]);
}:
function del(){
alert([del, document.detachEvent]);
}
};

In one shot we have created a unique add reference, a named function, plus the right one for the event object. Now guess what's up if we invert the order putting the IE version at the end ... add will be the last option ... the one with addEventListener, got the point?

As Summary

I am pretty much sure I'll be criticized again and only for the last part of this post where obviously things work but somebody will argue about future IE9 sci-fi behavior or stuff like that ... well, that day my library will be deprecated in any case and, if needed, it's easy to implement over my Re Solution

var event = {
add:(function(add){document.addEventListener?
(add = function add(){
alert([add, document.addEventListener]);
}):
(add = function add(){
alert([add, document.attachEvent]);
}); return add
})()
};

Now let's see if the most interesting analysis about functions expressions and declaration will keep ending up with the wrong suggestion, rather than mine ... kinda curios, still hopeful though.

Sunday, October 11, 2009

Named function expressions demystified II

Update If after this reading things are still the same, please read the part 3 of this post, thanks.


I have been criticized just for fun and in a impulsive way without analysis or tests (I am not talking about Juriy who gently replied with interesting points in the part 1 of this post - and I replied back).
First of all, if the purpose of an article is to describe a behavior and provide a solution, there should not be any challenge or run for the copyright ... we are developers, and we want the best solution, for us and others, if this solution has been published.

Specially for a complicated language as JavaScript is, Virtual Machine and cross browser troubles speaking, is really difficult, sometimes impossible, to find the ultimate and perfect solution, so let's keep the argument in a professional way, agree?

What Is Wrong With Juriy Solution

Somebody does not get it, and it could be my fault. So this is about inconsistencies, and I'll show you Juriy code to avoid any kind of misunderstanding, OK?

var fn = (function(){

// declare a variable to assign function object to
var f;

// conditionally create a named function
// and assign its reference to `f`
if (true) {
f = function F(){
// now try to create a setTimeout here
// assuming we need it

// error, there is no F reference
// anymore in this context.
// This function obviously exists and
// the entire point is to find a solution
// to replace arguments.callee
// so do you think is a good design
// we cannot use the function name
// with every browser?
setTimeout(F, 1000);

// insted we have to use another name
// but there is NO REASON to do this
// if you understood my precedent post
setTimeout(f, 1000);

// so the purpose is to make function
// call possible via name and the solution
// is to do not use the function name
// am I the only one spotting
// inconsistency here?

alert(f == F); // FALSE
// because F was the last option
// and F has been referenced to null
}
}
else if (false) {
// same as above
f = function F(){ }
}
else {
// same as above
f = function F(){ }
}

// Assign `null` to a variable corresponding to a function name
// This marks the function object (referred to by that identifier)
// available for garbage collection
var F = null;

// NO, this does not mark anything
// this is another layer in JScript
// the function exists, as exists the last one
// if we are nullify a reference, the garbage
// will discard the function because not
// referenced ANYWHERE in this contest

// This behavior is EXACTLY THE SAME
// if we have last option callback
// in IE since the last function reference
// will be the only one, then other functions
// will be collected

// Moreover, with "Re Solution"
// the function is trapped in the reference
// where the reference HAS THE SAME NAME
// this means we have THE FUNCTION NAME
// as valid one in the current scope
// NO ALIASES, and garbage is fine


// return a conditionally defined function
return f;
})();


Re Solution

To keep best compatibility the last option could be a bit messy in Opera or old Safari. That is why I have suggested my Re Solution.

var fn = (function(){

// declare the FUNCTION NAME we want to use
var F;

// conditionally create a named function
// and assign its reference to ITS NAME
if (true) {
F = function F(){
// EASY!!!
alert(F == arguments.callee); // TRUE
setTimeout(F, 1000);
}
}
else if (false) {
// same as above
F = function F(){ }
}
else {
// same as above
F = function F(){ }
};

// In this cotext there is
// ONE AND ONLY ONE
// reference to function F
// being the reference evaluated
// AFTER function declaration
// It does not matter if
// there are other functions
// with the same name because
// the reference, which comes after
// WILL POINT TO THAT FUNCTION
// which is a named one

// EASY ???
return F;
})();


As Summary

I hope things are finally clear for everybody. I hope Juriy will get my point, and I am always ready to negate everything I wrote as soon as somebody will demonstrate it is wrong. Again, we are developers, there's no trophy here if we want make something public for developers community.

Saturday, October 10, 2009

Named function expressions demystified

Update If after this reading things are still the same, please read the part 2 of this post, thanks.



This is a re-post, and few considerations, about the good Juriy article, which I suggest for every JavaScript developer with a deeper knowledge than just an API (jQuery or others).

Github For Everything!

My first consideration is about github, something I've never used that much since via Google Code I feel pretty comfortable with subversion. I find truly interesting the way Juriy is tracking his documentation, I've never thought about an article, as my old JavaScript Prototypal Inheritance could be, in a code repository as kangax did: good stuff!

My Alternative Solution

There are few extra consideration to do over Juriy explanation, plus minor inconsistencies. The first thing is that Internet Explorer basically manages Function expressions and Function declarations in the same way, there's no such VS in the middle.
The fact we assign the function to a whatever named variable does not make any difference:

alert(F); // (function F(f){/*IE Function*/return f})

F((function F(f){/*Function Declaration*/return f}));
F((function F(f){/*IE Function*/return f}));

var f = (function F(){return F}); // <== which F?
function F(){/*IE Function*/}; // this one!

alert(f()); // function F(){/*IE Function*/};
We can play with above IE traps for ages but the point is simple: the last defined function with that name, will simply take the place of the other one, if any, in the same scope, and at the end of its resolution, before code execution.

What IE does is basically a top-down parsing over functions without taking care at all about code execution or normal and expected syntax execution flow.
This simply means that return whatever, var whatever = function whatever(){} ... does not change anything for our loved IE:what we see or what we expect is not what will be, otherwise IE would have been a perfect browser.
To better understand what I am talking about, this example should speak for me:

var f = 123;
alert(F); // last function
(function(){
alert(F); // (function F(){alert(f);return arguments.callee})
var f = (function F(){alert(f);return arguments.callee})();
// undefined
})();
function F(){};

After these two snippets is quite logical understand this behavior:
  1. scope resultion
  2. function resolution plus optional inline assignment, if any, before next function resolution
  3. code interpretation/execution over scope resolution

Accordingly with this Richard Cornford post, in JScript every function is performed sending the execution context, a behavior somehow similar to the injected context via eval in Firefox few months ago.
The latter one has been considered a security hole ... same kind of hole we need to deal with IE on daily basis every time we would simply chose a name for a bloody function.

My Solution

Juriy perfectly knows my point of view about this problem, he knows it so well that his addEvent solution example is created ad hoc to make mine inefficient (and I'll tell you later why).
It does not matter, as long as I can use the same example, avoiding IE4 support ...

var addEvent = (function(){
var docEl = document.documentElement;
if (docEl.addEventListener) {
/* return */ function addEvent(element, eventName, callback) {
element.addEventListener(eventName, callback, false);
};
} else {
// IE has to be the last option
// other addEvent will be "lost"
// cause this will be the only named reference
// in this scope ...
function addEvent(element, eventName, callback) {
element.attachEvent('on' + eventName, callback);
}
};
return addEvent;
})();

The key is simple, and is based exactly over same considerations and suggestions Juriy gives in the Alternative solution paragraph, except my suggestion uses an explicit last option callback, without requiring var this or that plus var this or that = null in any place, and for this purpose.

Indeed, for the same reason Juriy did not perform this task at the end of his latest suggestion and before the returned function:

if (typeof docEl.addEventListener != 'undefined') {
attachEvent = addEventAsProperty = null;
return addEventListener;
}
elseif (typeof docEl.attachEvent != 'undefined') {
addEventListener = addEventAsProperty = null;
return attachEvent;
}
addEventListener = attachEvent = null;
return addEventAsProperty;


totally boring and absolutely anti pattern, on daily basis and real case scenarios, with my suggestion there is absolutely no need to remember to nullify variables used only to refer inline assignments and, moreover, only as Internet Explorer workaround!!! That's too much, I mean we have to change our code, change JS logic, to support such drama JS engine, we even need to write more and nullify everything? No way!

But It Could Be Inefficient

The only real side effect about my suggestion, surprisingly working in Safari 2 as well and solving its problems with names, is that if we have to deal with two different versions of IE in the same scope, we cannot use the "last definition" trick, 'cause one out of 2, 3, or 234567 versions of the most problematic browser since Web epoc, still Internet Explorer and JavaScript speaking, will mess up like a charm ... to be honest, IE4 days, the one without try catch and much more support, are far away from 2009, and I've never had to deal with such problem but in this case, there is nothing better, so far, than Juriy proposal.

Update
In my addEvent example Opera, thanks to its duality, will behave IE like. This is not a problem, since addEvent will work in any case, but we can return if we would like to force Opera with addEventListener (avoiding Safari 2 then). To solve this problem, when necessarym we can use the best from both proposal.

Re Solution


var addEvent = (function(){
var docEl = document.documentElement,
addEvent;
if (docEl.addEventListener) {
addEvent = function addEvent(element, eventName, callback) {
element.addEventListener(eventName, callback, false);
}
}
else {
addEvent = function addEvent(element, eventName, callback) {
element.attachEvent('on' + eventName, callback);
}
}
return addEvent;
})();
Quite semantic, isn't it? ;)
The principle is still the same suggested by Juriy except there is nothing to nullify, just a reference to return, and being based on variable assignment, we can have 2345IE versions in the if else without problems at all.

As Summary

In Internet Explorer there is no difference between function expression and function declaration, this is the whole point of this post, plus the updated suggestion which makes things a bit more logical, from a developer point of view - addEvent is a well defined reference, and that's what we need.
The var F = null; in Juriy suggestion is useless for IE. References comes after, in the interpretation flow, while references come before in the execution one. var F = null; will nullify a reference, it won't mark anything for the IE garbage collector.
Juriy article is in any case a must read as soon as we understand JavaScript scope and lambdas, and specially if we would like to support multiple browsers.
Hopefully these gotchas will disappear with ES5 and the next "dreamed" IE9 with its totally new fabulous V8 engine ( OK, OK, ... let me dream please ... )
The day IE will disappear from browsers panorama I'll be the most happy and drunk web developer in the area but until that day, we can say the panorama is still weird, at least well explained, and with all possible solutions, we have choices!

Friday, March 21, 2008

How to inject protected methods in JavaScript - Part II

As a performances maniac, I've found another way to inject protected methods, or something similar, without unnecessary overload of each public method.

Of course, precedent way is definitively more clear, linear, but if you have a constructor.prototype with a lot of private methods, the overload process will be a wall in front of method execution speed.

Each time you will use a public method, you have to set, and unset, every protected method, and at the same time, as explained in my precedent post, you cannot send the object outside during public method execution, because it will expose every method, protected included.

This new proposal is based on a Function like strategy, applied to instances: apply, and call. Please have a look at this prototype function:

function prototype(constructor, public, protected){
// webreflection - mit style
if(protected){
public.apply = function(callback, arguments){
return (callback.charAt(0) === "_" ? protected : this)[callback].apply(this, arguments);
};
public.call = function(callback){
return this.apply.call(this, callback, Array.prototype.slice.call(arguments, 1));
};
};
public.constructor = constructor;
constructor.prototype = public;
return public;
};

A usage example should be this one:

function MyMath(value){
this.value = value;
};
prototype(
MyMath,
{doStuff:function(){
return this.value * this.value;
}},
{_doStuff:function(){
return this.value + this.value;
}}
);

The first sent object will be the prototype of MyMath constructor, while the second one will contain protected methods.

About performances


As you can see in the simple prototype function, there's no override and no overhead for both public and protected methods. This means that you can use a public method directly and without problems:

var num = new MyMath(3);
num.doStuff(); // direct, fast as regular prototype


About protected methods


These simply "does not exists" :)

var num = new MyMath(3);
num._doStuff(); // error

Protected methods are not directly accessible even from instance itself. This means that these methods are safe and not mutable, if used object is created in a private scope, or runtime as showed before.

How to use protected methods



var num = new MyMath(3);
alert(num.call("_doStuff")); // 6

Apply and call, in this case, are used with instance to call a method that, if contain an underscore as first prefix char, will be one from protected prototype, otherwise will be one of the public prototype. Sounds weird?

// full example
function MyMath(value){
this.value = value;
};
prototype(
MyMath,
{doStuff:function(){
return this.value * this.value;
}},
{_doStuff:function(){
return this.value + this.value;
}}
);

var num = new MyMath(3);
alert([
num.doStuff(), // 9
num.call("doStuff"), // 9
num.call("_doStuff") // 6
].join("\n"));

num._doStuff; // undefined


Why do I call them protected


If everyone can call a method, it does not make sense to call them protected.
But this time, the meaning is not the same of classical inheritance, but it is more close to the word itself: proteced.

The main goal is to have a not common or usual way to call methods, specially for libraries developers.
Every API could be based on public methods, while authors could choose to call a protected method when their need them.
This is basically a transparent layer between the developer and the final user: who will use num.call("doStuff") when you can do this: num.doStuff() ?

I know I am not so good to explain my ideas, so I hope someone will find this useful. Have a nice easter ;)