My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label common. Show all posts
Showing posts with label common. Show all posts

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.

Tuesday, April 08, 2008

Famous documentation and the dark side of "this" !

The good thing of internet is that you can find a lot of free documentation.
At the same time, the bad thing of internet, is that this documentation is rarely updated.

It could be a "guru documentation" or it could be a newbie documentation, but in both cases, it doesn't matter because it is probably wrong, not updated, or too generic.

This post has not enough space to describe every error you can find on, and off line ... so let me start with some true example about a common misunderstood referer, the this one.

Douglas Crockford and Private Members in JavaScript


This page is famous enough, and I suppose that every true JavaScript developer has read them at least once.
The main error in that page is described in this sentence

By convention, we make a private that parameter. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

We know, or maybe we don't, that everything without a prefix will be executed in the global scope or in nested closure, if any. But even if a function is created inside a method, it fortunately does not make sense to call a function that has not been assigned as instance method and find a this reference inside.

// guys, this function ...
window.testMe = function(){};

// is exactly the same of this one
function testMe(){};

// or this one in a global scope
var testMe = function(){};

The main reason we do not need to use window when we call a global method, or function, is that everything in JavaScript is virtually executed like in a global window with statement (that's why write window.open is redundant and nothing else ... and Stargate code is totally redundant too :D).

// this code ...
window.onload = function(){};

// is exactly the same of this one
onload = function(){};

onload();

// that is virtually similar to ...
with(window){
onload();
};

Let's focus on the onload example in the middle ... ok? Who will be the this referer if we do not use call or apply Function.prototype methods? window, of course.
And as window has a self property, that a link to window itself, if we use alert(this === self); it will be true every time we will use onload();
If we assign onload function as object method

onload = function(){
alert(this === self);
alert(this === window);
};
var o = {};
o.onload = onload;

... we will read two alerts with two false instead of two true value.
This simply means that to use a function that has not been assigned as method, or better, that is not called from a method, the this reference will be the global object.

onload = function(){
alert(this === window);
};
onload(); // true
var o = {onload:onload};
o.onload(); // false

function useCallback(callback){
callback();
};

useCallback(o.onload); // false again

I do not really know why Doug defined this an error in ECMA Specification, but if it really is, what could be the logic behaviour, an "unpredictable" default this referer even if the nested function is not inside an instance constructor?
I don't think so.

The intrinsic constructor Factory Design Pattern


Thanks to this "error", we could use a constructor in two ways or recognize when it has been called with new or as function.
If it is an error, it couldn't be possible to know this kind of useful information.

function Person(name, age){

// this is true only if we used
// new before Person constructor
if(this instanceof Person){
this.name = name;
this.age = age;
} else

// otherwise we used the constructor
// as factory design pattern (in this example)
return new Person(name, age);
};

// these two lines do the same thing: create a Person instance
var me = Person("Andrea", 29), // doyou like python style, don't you?
you = new Person("You", null);

alert(me instanceof Person); // true
alert(you instanceof Person); // true

Anyway, as I wrote in my recent and updated documentation, that passed totally unobserved, we do not need a that variable for nested private function.

function Person(name, age){
function setNameAndAge(){
this.name = name;
this.age = age;
};
// to call setNameAndAge as private
// method we do not need a that
// but only call or apply Function.prototype
// methods to inject instance as this referer
setNameAndAge.call(this);
};
alert(
(new Person("Andrea", 29)).name // Andrea
);

Finally, I have to admit that Douglas Crockford is my favourite JavaScript professor, and it's basically thanks to him that I know what I know about JavaScript. He wrote a lot of interesting JS stuff, and some document is truly updated, explaining for example errors wrote in old one.

My programming style has evolved since then, as any good programmer's should. I have learned to fully embrace prototypalism, and have liberated myself from the confines of the classical model.

Every programmer should evolve because in this sector knowledge is never enough. So thanks a lot Doug, but please update your 2001 doc writing something more about this, that, scope, injected this, and closures :D (a link to this post should be appreciated as well)

Ross and Dustin in Pro JavaScript Design Patterns


Differently, here we are in late 2007 ... December 2007
For some reason, few days ago someone posted again this book in Digg ... and for the first time, I read about them.

It seems to be really a good book, but without reading them, I've just downloaded examples trying to imagine what are these used for.

Fortunately, and thanks to Apress or authors decision, these sources are free and well organized inside chapter folders, each file with dedicated paragraph.

Well done ... but at the third chapter, I've read a pseudo "horror" in file 3.07 ...

var Class = (function() {

// Constants (created as private static attributes).
var UPPER_BOUND = 100;

// Privileged static method.

// ... that will never work, where is the function?
this.getUPPER_BOUND() {
return UPPER_BOUND;
}
// Return the constructor.
return function(constructorArgument) {
//
}
})();

Forgetting the missed = function, that could be a common error during quick development, getUPPER_BOUND is a privileged method of the global scope, aka window, and it is not static, it is like a window.getUPER_BOUND call, where this is obviously the window itself.
As I wrote few lines before, if we use this inside a function it will refer to window object. That's why after we can see a wrong example like this one:

var Class = (function() {
var constants = {
UPPER_BOUND: 100,
LOWER_BOUND: -100
}
// again ...
this.getConstant = function(name) {
return constants[name];
}
return function(constructorArgument) {
//...
}
})();

// anyway ... Error!!!
Class.getConstant('UPPER_BOUND');

alert(Class.getConstant); // undefined
alert(getConstant); // expected function


I am pretty sure that if this code is the one showed to explain privileged, that chapter could be full of errors ... please update them putting correct code and free corrected page inside the zip ... otherwise, sorry for this correction.

Finally, Dustin and Ross are two JavaScript ninjas, and reading the rest of the code it seems that I absolutely need to find that book because I do like design patterns and I am so curious to know how are their implementation (good stuff guys!).

Conclusion


I am the first one that writes horrible code, and probably I've even forgot what I wrote one year ago and where ... so the only suggestion I could write is that if you find something interesting, or something that you did not know, look for something else and look every time for the date that document has been published.

Have fun with self instruction, and never stop ;)