views:

724

answers:

4

Hi to all, i'm quite a newbie in javascript, and i'm spending some time trying to create namespaced objects in js.

Now, that's what i'm trying to do:

MainObject = function() {

    var privateVariable = "i'm private";

    var privateMethod = function() {
        // doSomething
    }

    this.publicMethod = function() {
        // doPublicSomething
    }
}

MainObject.prototype.nested = function() {

    this.publicNestedMethod = function() {

        // that's not working at all
        this.privateMethod(privateVariable);

    }
}

MyObject = new MainObject();

MyObject.publicMethod();
MyObject.publicNestedMethod();

I tried to include the nested class inside the first one, but it's not working also if i try:

this.nested = function() {

    var mainObject = this;

    return {
        publicNestedMethod = function() {
            mainObject.privateMethod();             
        }   
    }
}();

Someone can help me please? i'm gonna loose my mind on this.

Phaedra.

A: 

What OO system lets you inherit private methods? Part of being private is being unaccessible from other objects.

In JS in particular, "private members" are really just local variables of the function where they are declared. JS doesn't have typical OO notions of "class", "inheritance", "public", and "private", so you can't expect to copy your OOP techniques verbatim from other OOP languages.

Gabe
In java if you are creating a inner cass, you can access the main class private methods, i'm quite sure about this. Prototyping the nested object, i'm adding it to the main object instance. So i was expecting that it works like a closure givin me access to the variables of the main object.
Phaedra
Remember that JavaScript is like Java in name only. They are so different that you can't expect anything in JS to work the same as it does in Java. Since JS doesn't have classes per se, it doesn't have inner classes either.
Gabe
A: 

Closures are a lexical feature, not a semantic one. If the object is outside the lexical scope of another, it can no longer be "nested" and access the former's local variables. In the code of your nested function/class, there's no such thing as this.privateMethod, because privateMethod is never made to be a property of MainObject. It's simply a local variable inside a function.

There's no such things as "private properties", "private methods" or "private members" in JavaScript. Hell, there's no such thing as a "class". Some people like to emulate private members using local variables as above, but doing so results in cases like this, where the discrepancy between the two concepts comes and bites one in the behind.

To conclude, it is a bad idea to write Java code, with all its OO techniques in JS, just as it is a bad idea to write C code, with all its pointers and unbounded buffers, in C#. Sure, in both cases you can do it, but you would be failing to appreciate and exploit the language's features this way.

And now that I'm done with the rant, you can do something like this to get "namespaced" functions:

MainObject = function() {
    var privateVariable = "I'm private";

    var privateMethod = function() {
        alert('Private');
    }

    this.publicMethod = function() {
        alert('Public');
    }

    this.nested = {
      publicNestedMethod: function() {
        privateMethod();
      }
    };

    // or

    this.nested = (function() {
      var nestedPrivate = 5;

      return {
        publicNestedMethod: function() {
          alert(nestedPrivate);
          privateMethod();
        }
      };
    })();
}

MyObject = new MainObject();

MyObject.publicMethod();
MyObject.nested.publicNestedMethod();​
Max Shawabkeh
what if : this.nested = function() { var privateNested = function() { } return { }}();
Phaedra
You'll need to add parentheses around the function (declaration vs expression, see http://yura.thinkweb2.com/named-function-expressions/). Other than that, it's exactly what a closure is - you're encapsulating local variables used at function creation time. Edited the answer to show an example.
Max Shawabkeh
So that's what i was searching for, i think. or Not? i was missing the parethesis..
Phaedra
I'm not quite sure what it was you were searching for, but looking at your code, the main problem is that you treated local variables as object properties.
Max Shawabkeh
A: 

This is my attempt at - Classical Object Oriented Programming style JavaScript library - http://code.google.com/p/oopsjs/

Rajendra
A: 

Using the convention of underscore for "private" methods is a reasonable way to keep things organized.

MainObject = function() {

   this._privateVariable = "i'm private";

   this._privateMethod = function() {
      // doSomething
   }

    this.publicMethod = function() {
      // doPublicSomething
    }

}

morgancodes