9

I am trying to settle on a method that will provide me the most elegant way of wrapping my code in Namespace/Unit like objects. For example Google Maps API's var a = Google.Maps.Foo();, which I think seems quite clean.

I'd like it to enclose (if that is the right term) the jQuery No Conflict $ sign as well.

So far I am liking:

// Top level container for sub objects
var myApp = myApp || {}; 

// An object to be held in myApp     
(function( skillet, $, undefined ) {

    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );

        return "Fried!";
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }   

}( window.myApp.skillet = window.myApp.skillet || {}, jQuery ));

Can anyone expand on this, point out potential problems, or just offer a better methodology in general?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Gga
  • 4,311
  • 14
  • 39
  • 74
  • 2
    There is never a *most* elegant way to do something, because elegance is subjective. – Philipp Mar 27 '13 at 12:54
  • Everything you need to make the best decision for you is here: http://stackoverflow.com/questions/881515/javascript-namespace-declaration – NinjaNye Mar 27 '13 at 13:11
  • @NinjaNye Ah yes, that is where the code from, I am trying to expand upon it really. – Gga Mar 27 '13 at 13:16
  • Your pattern is really fine. What do you want to expand? – Bergi Mar 27 '13 at 13:19
  • @Bergi Hmmm just determine if the method is the best available and what flaws it may be open to really. – Gga Mar 27 '13 at 13:27
  • 1
    To my mind, it would be better to define all functions as private, then expose as public whatever is necessary, `en bloc` in a set of statements at the end. For example, `function fry() {...}` then `skillet.fry = fry;`. This has the dual advantage of allowing internal function calls not to require the `skillet.` prefix, and for public methods to be easily observed/adjusted. – Beetroot-Beetroot Mar 27 '13 at 17:46
  • @Beetroot-Beetroot Really nice. Now I'm only exposing one method publicly, before I was exposing a few due to making async requests. Good stuff, thanks. – Gga Mar 27 '13 at 18:39
  • @Philipp elegance here encapsulates robustness and simplicity, so less subjective than you might think ;) – Gga Apr 03 '13 at 16:27

1 Answers1

11

Check this JavaScript Module Pattern and this Learning JavaScript Design Patterns

Module example:

var MyModule = (function($){
  var MY_CONSTANT = 123;

  var _myPrivateVariable = 'TEST MEH';
  var _$myPrivateJqueryObject = $('div.content');

  var _myPrivateMethod = function(){
    alert('I am private!');
  };

  var myPublicMethod = function(){
    console.log('Public much?');
  }

  return {
      myPublicMethod : myPublicMethod 
  };

})(jQuery);

MyModule.myPublicMethod();

Class example:

function Person(name, age){
   this.name = name || '';
   this.age = age || -1;
}

Person.prototype.greet= function(){
   console.log('Hi! My name is' + this.name + '. Old ' + this.age + ' I am.');
}

var person = new Person("John", 12);
person.greet();
kayz1
  • 7,260
  • 3
  • 53
  • 56
  • Nice articles :) (although the second one is a bit clumsy) – Simon Mar 27 '13 at 13:05
  • It's a book :) by Googler Addy Osmani – kayz1 Mar 27 '13 at 13:11
  • 1
    The unescaped single quote hurts our eyes ;) – Peter Herdenborg Mar 27 '13 at 13:14
  • There is no need to prefix any variables with underscores. – Bergi Mar 27 '13 at 13:16
  • Peter Herdenborg oops :) @Bergi - sure, but it's nice to know what is private/public since there is nothing like that in JavaScript :) – kayz1 Mar 27 '13 at 13:17
  • Since there is nothing like that, you don't actually need it. If you've got a variable, you check its scope, and if you want to know what gets exported you look at the return statement object literal. – Bergi Mar 27 '13 at 13:21
  • True, but when you have to navigate a few K javaScript SLOC every hint is welcome :) It's a good practice event in statically typed programming languages (C#, Java...). – kayz1 Mar 27 '13 at 13:31
  • 2
    It should be noted that these two patterns do not compete with each other. The Module pattern is strictly for creating a singleton namespaces (or a set of related singleton namespaces), whilst the Class pattern gives you something that forms the basis for multiple instances. With the Class pattern, you should also be aware that (in the way it's written above) it needs to be called with `new` - a point which is thoroughly discussed [here](http://ejohn.org/blog/simple-class-instantiation/) - if you can follow every word, then you are doing well - I re-read it from time to time. – Beetroot-Beetroot Mar 27 '13 at 20:58