2

This is such a fundamental question, that I'm sure it's a duplicate, so I apologize in advance, but is this how I write an object such that I use by saying:

myApplication.myFirstMethod(x);
x = myApplication.myFirstMethod();

Here's the code:

myApplication = {};
(function() {
    myApplication.myFirstMethod = function() {
        var local = {};
        if (arguments.length) {
            local.result = arguments[0];
        }
        return local.result;
    }
    myApplication.mySecondMethod = function() {
        var local = {};
        if (arguments.length) {
            local.result = arguments[0];
        }
        return local.result;
    }
})();
Phillip Senn
  • 46,771
  • 90
  • 257
  • 373

2 Answers2

3

jsFiddle Demo

A more object oriented approach would be to use instantiation and prototype.

Setup

var Application = function(){
 this.local = {};  
};
Application.prototype.Value = function(){
 if (arguments.length) {
    this.local.result = arguments[0];
 }else{
    return this.local.result;
 } 
};

Used

var app = new Application();
app.Value(6);
alert(app.Value());//6

From a jQuery point of view, they will first screen to see if there are arguments, this code is direct from their source for the val function:

val: function( value ) {
    if ( !arguments.length ) {
        var elem = this[0];
...

It then goes on to use the element's native API and some other metrics to get the value for the element (In general, the only type of elements which will return a value from val are going to be elements such as input, select, etc. - form elements basically).

At the end of the if block it attempts to return various results based on if it found a value attached to the element (or set of elements). This guarantees that the clause of "setting" never executes when a "get" is encountered. If the case is that "set" is being used it goes through a slightly complex set of code to properly set a value to the element.

The reason that the code shows val: function() is because it is part of an object which is being used to "extend" the jQuery prototype using jQuery's extend functionality.

This is the exact code in a jsfiddle of jQuery's val function

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • Is this really how it's done? I'm just asking because I'm a bit intimidated by the prototype keyword. I'm going to look at jQuery and see how Resig is doing it. – Phillip Senn Oct 09 '13 at 16:07
  • @Phillip - jQuery does indeed use `prototype`. In jQuery, `prototype` is stored in the `.fn` location. This is where *all* extensions for jQuery hook in to. http://stackoverflow.com/a/16026484/1026459 – Travis J Oct 09 '13 at 16:11
  • @Phillip - See my edit for some more details on jQuery's implementation of something similar (the `val` function). – Travis J Oct 09 '13 at 16:21
  • Thanks Travis! Now, what about this.local.result? If I have a 2nd method, then this.local.result will be in its scope as well. I'm trying to keep the value of arguments[0] local only to each method. – Phillip Senn Oct 09 '13 at 16:26
  • @Phillip - Using `this.local` will attach `local` to the `Application` object (thus making it scoped to the Application). If you would like to keep it scoped only to the function, then it should not be used with `this.` and instead with `var `. The reason is that, when `new` is used it will create a function object from the function. At that point `this` will refer to the instance of that object instead of `window` when there is no parent scope. Attaching to `this` essentially attaches to the object. In conclusion, if you want the variable localized, use `var` inside of the extended function. – Travis J Oct 09 '13 at 16:30
  • Extra clarification on `new` and `this`. Using `new` is what allows the prototype to be attached to the function (it essentially triggers the attachment). As a result, when inside of the scope of a function that is attached to the prototype, `this` will always refer to the current instance (Application in my simple example). Whereas `var` will only be scoped to the current `function(){}` block that it sits in. Once that block loses scope, the value of `var` will be lost. – Travis J Oct 09 '13 at 16:33
  • Hence the need for a closure - to keep the value after the function executes. I think I might ask the same thing in a new question so that I we can talk about mySecondMethod. – Phillip Senn Oct 09 '13 at 16:46
3

There are many patterns for creating objects like this and everyone has their favorites. Addy Osmani does an excellent job of summarizing the most popular patterns in his Javascript Design Patterns "book". Specifically, this section:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#designpatternsjavascript

I reread this semi-annualy just to make sure I'm keeping all the patterns in my quiver.

dtex
  • 71
  • 2