Reverse string

JavaScript performance comparison

Revision 10 of this test case created

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

</script>
<script>
 window.ns = function( namespace, callback ) {

    var components = namespace.split('.'),
        scope      = components.shift(),
        method     = components.pop(),
        context    = window[scope],
        i = 0, property;

    if(context === undefined) { context = window[scope] = {}; }

    for(i; i < components.length; i += 1 ) {
       property = components[i];
       if(context[property] === undefined) { context[property] = {}; }
       context = context[property];
   }

   context[method] = callback;
};




var APP = {};
APP = (function (mod, $) {

   var // Private properties
       _ = {
           is_initialized : false
       },

       // Public properties
       module = $.extend(mod, {
           NAME          : 'APP',
           VERSION       : '1.0.0',

           // Set true to see notifications (pubsub pattern) on console log
           // Set false before production !!!
           DEBUG_MODE    : false
       });

   module.init = function(fnCallback) {

       if(_.is_initialized) { return; }
       _.is_initialized = true;

       _.setLogger(module.DEBUG_MODE);
       _.initPubSubPattern();

       APP.checkDepencies(module, ['$.subscribe', '$.unsubscribe', '$.notify']);

       // Just a DEBUG warning
       console.log('**** WARNING ' + module.NAME + ' v' + module.VERSION + ' ****');
       console.log('***** DEBUG MODE IS ON *****');
       console.log('********* WARNING **********');

       // getProperty event handler
       $.subscribe('/property/get', module.getProperty);
       // isLogged event handler
       // $.subscribe('/isLogged/get', module.getIsLogged);
       // Initialization event handler
       $.subscribe('/app/initialization/success', module.onAppInitializationSuccess);

       // Call custom initialization method
       fnCallback();

   };
   module.initModules = function(arrModules) {

       if(!arrModules.length) { return; }

       // Initialize all modules
       $.each(arrModules, function(i, item) {
           APP.modules[item].init();
       });

   };


   module.onAppInitializationSuccess = function() {
       console.log('Should be overwrited::', module.NAME, 'onAppInitializationSuccess');
   };

   /**
   * Custom logger
   */
   _.setLogger = function(enable) {

       module.DEBUG_MODE = enable;
       try {
           console.log();
       } catch(error) {
           window.console = {
               log   : function() { return false; },
               dir   : function() { return false; },
               debug : function() { return false; },
               error : function() { return false; }
           };
       } finally {
           if(!module.DEBUG_MODE) {
               console.log   = function() { return false; };
               console.dir   = function() { return false; };
               console.debug = function() { return false; };
               console.error = function() { return false; };
           }
       }

   };

   /**
   * JQuery pubsub design pattern definition (MVP).
   *
   * $.subscribe(<String>, <callbackFunction>);
    * $.unsubscribe(<String>, <callbackFunction>);
    * $.notify(<String>, <value>);
    *
    * Usage example:
    *    $.subscribe('/custom/event', cbFunc);
    *    $.notify('/custom/event', {success:true});
    */
    _.initPubSubPattern = function() {

        (function($) {

            var o = $({});

            $.subscribe = function() { o.on.apply(o, arguments); };
            $.unsubscribe = function() { o.off.apply(o, arguments); };
            $.notify = function() {
                console.log(arguments);
                o.trigger.apply(o, arguments);
            };

        }(jQuery));

    };

    /**
    * @param ns_string {String} String with path of the package
    **/
    module.namespace = function (ns_string) {

        var parts = ns_string.split('.'),
            parent = APP,
            i,
            len;

        if(parts[0] === module.NAME) {
            parts = parts.slice(1);
        }

        len = parts.length;
        for(i=0; i<len; i+= 1) {
           if(parent[parts[i]] === undefined) {
               parent[parts[i]] = {};
           }

           parent = parent[parts[i]];
       }

       return parent;

   };

   /**
   * @param caller        {Object} Object of the module calling this method.
   * @param arrDependency {Array}  List of dependencies to be checked.
   **/
   module.checkDepencies = function(caller, arrDependency) {

       var i = 0,
           j = 0,
           len = arrDependency.length,
           parts = [],
           parent = window;

       try {
           for(i; i<len; i += 1) {
               parent = window;
               parts = arrDependency[i].split('.');
               for(j = 0; j<parts.length; j += 1) {
                   if(parent[parts[j]] === undefined) {
                       throw "[" + arrDependency[i] + "] is not defined!";
                   }

                   parent = parent[parts[j]];
               }
           }
       } catch(e) {
           console.log('');
           console.error('********* DEPENDENCY WARNING **********');
           console.error('<"' + caller.NAME + '">' + '::Dependency', e);
            console.error('********* DEPENDENCY WARNING **********');
            console.log('');
            mod = null;
            return false;
        }

    };

    return module;

}(APP, jQuery));

Preparation code output