Recently I got borred with the for loops and I added the “times” function on the prototype of Number. As a result, I can easily iterate over arrays or I can simply call a function how many times I want like this:

     (5).times(function(index /* zero based */){
           console.log(index);
     })
     //or using array length
     arr.length.times(function(){ ... });

     //optionally specify scope for the callback function:
    n.times(function(){ .... }, scope);

Together with this, I’m using another goodie. Whenever I have a function that expects a parameter which can either be a simple value or an array, convert that value to array in one line, like:

    var arr = [].concat(valueOrArray);

See below the source code.

/**
 * extend the Number prototype
 * @param func
 * @param scope [optional]
 */
Number.prototype.times = function(func, scope){
    var v = this.valueOf();
    for (var i=0; i < v; i++){
        func.call(scope||window,i);
    }
};

function test(valueOrArray){
    var arr = [].concat(valueOrArray)
    arr.length.times(function(i){
        console.log(arr[i]);
    })
}

test([1,3,4])
//output: 1   3   4

test(123)
//output: 123

As for the performance, I have tested the times function against the for loop, and it seems to give about same results at a first glance. Any feedback on this?

P.S. Iterating over arrays gets even easier by adding an 'each' function to the Array prototype. Adding to the prototype of standard JavaScript objects is a debatable practice, and should not be abused.

You should make use of the scope config option in components

.

  • in Ajax calls
    var MyPanel = Ext.extend(Ext.Panel, {
        doSave: function(){
    	Ext.Ajax.request({
    	    url: 'your_url',
    	    params: ....
    	    success: function(response){
    		response = Ext.decode(response.responseText);
    		this.onSuccess(response)
    	    },
    	    scope: this //the scope in which the success callback is called
    	})
        },
        onSuccess: function(){ .... }
    }

    In this example, specifying the scope is very useful. By default, the success callback on Ajax calls is executed with the scope being the browser ‘window’ object, which is not very useful. In the code above, we execute the success callback in the ‘this’ scope, ‘this’ being the instance of MyPanel which executes the doSave method. This is why we can safely call this.onSuccess(response), as ‘this’ is a MyPanel object, which has the onSuccess method.
    I find the scope config property very useful, so even though specifying the scope of a function is very natural in JavaScript, the fact that ExtJS made it so natural and easy deserves being noted. Well done ExtJS!

  • in Buttons
    {
        xtype: 'button',
        text: 'Save',
        handler: function(){
    	//do something on pressing the button
        },
        scope: myScope //scope of the handler
    }
  • with Stores
    new Ext.data.Store({
        //...other config options
        autoLoad: {
    	callback: function(){ ... },
    	scope: aScope //for the callback function after loading the store
        }
    })
  • in listeners
    new Ext.Panel({
        listeners: {
    	scope: window, //the scope of all listeners in this config
    	show: function(){ ... },
    	afterrender: function(){ ...this is 'window' }
        }
    })
  • in actions