Inspect Third Party Plug-in

Few days back, I came across a jQuery plug-in which had similar structure as described below

$.fn.NicePlugin = function( options){
   var config = {
		defaultProp1 : defaultVal1,
		defaultProp2 : defaultVal2
   };
   
   $.extend( config, options );
   
   // Few Function.. 
   globalVar = false;

   $( ".A, .B" ).on( "click", function(){
	if( globalVar ){
	    return;
	}
		
	globalVar = true;
	doSomeOp(callback(){
            globalVar=false;
	});
   });
}

I took a quick look, rubbed my eyes and took a closer look – oh what a gem!

A bit of context, I was investigating performance issue and from the profiler, trying to figure out why so much time are being spent on QSA calls. Profiler led me to this plug-in which was getting called after inserting elements with classname as either “A” or “B” in a loop

Wait! Did I just mention that this plug-in was getting called in a loop after DOM insertion ? Oh yea, and that sure leads towards disastrous profiler data. Here’s how

Every time code insert an element with either classname as “A” or “B” and calls this plug-in using the element, plug-in just does not care of the element scope. It scans through the DOM to find out how many element exists with classname as either “A” or “B” and attach a event handler to all such element.

However it does not have to! The only thing it needed to do was to manage the element and attach event handler to it. QSA call are just plain redundant.

Oh! that’s not the end of it – there are few other things which are wrong with this plug-in – such as

  1. With every plug-in call, number of event handler on any element increases and for no good reason. If you call this plug-in “n” time, the first node probably will have about “n” event handler! Now, count the total number of event handler that has been created for “n” node”. Do we need that?
  2. Usage of global variable (globalVar in code) to ensure that for a click, even though multiple click handler exists, just the first one gets executed.

Confused Array!!!!

Without much ado, let’s get to the code directly

var obj = [];

obj[ "a" ] = 10;
obj[ "b" ] = 20;
obj[ "c" ] = 30; 

console.log( obj.length );  // returns ZERO!!!

Experienced JS programmers would have seen the similar type of code, where in Array are being used as plain JS object and their response would just be – let’s fix this now!

The problem is the mixed usage which is possible cause of dynamic nature of the language. The usage in such a way does not cause any loss of data and you can just iterate it like a plain JS object as

for( var name in obj ){
   if( obj.hasOwnProperty( name ) ) {
      console.log( obj[name] );
   }
}

// following works too.. 
console.log( obj["a"] );

Any usage with respect to Array API would do nothing such as

    console.log( "Array Length => "  + obj.length ); //returns ZERO, since array has no elements. "a"/"b"/"c" are properties of array object! 
    console.log( obj[1] ); //returns undefined, no element in array! 

However in that case, why would choose to say that “obj” is any Array! It is not…