0

how to design objects in javascript with public and private methods?

how to access the private method private_method from API.get?

function API(){
    function private_method(){
        return 'weeee';
    }
}

API.prototype.get = function(){
    // access "private_method"
};
clarkk
  • 27,151
  • 72
  • 200
  • 340
  • a decent explanation http://javascript.crockford.com/private.html – John Hartsock Jun 24 '14 at 18:56
  • That isn't technically a method at all. It's a function that's scoped to the contents of a constructor. It won't have access to the member properties or methods of the object it belongs to. – JLRishe Jun 24 '14 at 19:09
  • @JLRishe, unless [bound](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) to `this`. – Frédéric Hamidi Jun 24 '14 at 19:11

4 Answers4

3

You can create a self-executing function that wraps private methods in the function's scope.

// Self-executing function
var API = (function() {

    function API() {};

    API.prototype.get = function() {
        // can call private_method.
        private_method();
    }

    // Accessible from the object created in this scope.
    function private_method() { }

    return API;

})();

This method prevents unnecessary code from being executed each time the constructor is called.

Here's a working fiddle: http://jsfiddle.net/7QM9h/

Hayes
  • 848
  • 4
  • 10
2

I'm not sure if this is what you're looking for: JavaScript private methods

You would need to make a var within API with all the functions you want to be private.

Essentially the outer object becomes a container that has these functions in it, but within the functions themselves they deal with the private information held by the private variable. The added functions wouldn't be able to be part of the prototype in order to make them private

function Restaurant() {

    var myPrivateVar;

     var private_stuff = function()   // Only visible inside Restaurant()
     {
         myPrivateVar = "I can set this here!";
     }

     this.use_restroom = function()   // use_restroom is visible to all
     {
         private_stuff();
     } 
}

(I know this would be better suited for a comment, I apologize)

Community
  • 1
  • 1
mrzepka
  • 346
  • 3
  • 7
2
function API() {
    var private_method = function() { return "weee"; }
}

To make private_method visible only inside of API, you should set it to a declared variable. However, this means that private_method is not a part of the API.prototype.

function API() {
    this.public_method = function() { return "weee"; }
}

Using this, would make it visible to all instances of API.

Sterling Archer
  • 22,070
  • 18
  • 81
  • 118
1

The other answers here aren't bad, but they aren't getting to the real heart of your question.

In actual fact, there is no such thing as a private method in JavaScript. Mostly, this is because there is no such thing as a method in JavaScript. Not really.

Now before a bunch of people jump down my throat, let me clarify that: there's no such thing as a method in the pure sense of a classically object-oriented language. In a classical OO language, if you created an instance method, the only way to invoke that method is against an instance of the class. In JavaScript, you can attach functions to an object prototype, and they're treated as methods when invoked against an object that has that function in its prototype chain, but at the end of the day, that "method" is really just a function that acts like a method when its invoked a certain way.

You can look at this one of two ways: either JavaScript sucks because it doesn't support basic things like methods or JavaScript is awesome because you can have things that basically act like methods but can be used in more flexible ways too. I prefer the second perspective, but YMMV.

So, back to your question. The short answer is "JavaScript doesn't really have methods, so it can't really have private methods." The longer answer is "you can simulate private methods by exploiting the function scope of JavaScript." I say simulate because this approach doesn't really result in a method, but it does effect functionality hiding. To do this, you would use an immediately-invoked function expression (IIFE) to make sure the private function (remember: not really a method) isn't available externally:

var API = (function(){

    var secrets = {};
    var nextId = 0;

    // in function scope here; anything declared here won't
    // be available externally
    function set(public, secret) {
        // we can use 'this' here, but be careful!
        // if we don't call this function correctly,
        // 'this' will be bound to the global scope


        // here we set a normal (public) instance variable
        this.message = 'not secret: ' + public;

        // here's how we can simulate a private "instance varaible"
        secrets[this.id] = secret;
    }

    function API() {
        this.id = nextId++;
    }

    API.prototype.public = function() {
        // we can't call 'this.secret()' here because secret is
        // not a method on this object

        // we can call secret(), but that will not do what we want:
        // it will break because the global scope doesn't have the
        // variable we need

        // we can, however, do this:
        set.call(this, 'hello world!', 'i am secret');  
    }
    API.prototype.tellSecret = function() {
        return secrets[this.id];
    }

    return API;
})();

var api = new API();
api.public();
console.log(api);   // won't print any secret info; we also
                    // can't call api.secret()
console.log(api.getSecret());

In this manner, we've simulated the hiding of data and functionality. Note that we had to give each API a unique ID. However, there is a vulnerability here: since id is a public property of each instance of API, you could set it to another number, and access the secret information of another object! You could use Object.prototype.defineProperty to lock down the id property and close this vulnerability.

I hope this highlights some of the issues involved with hiding/restriction in JavaScript.

Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • Very good explanation, however, i didn't catch much of the simulation example, except that it seem complicated to achieve. – AXMIM Jun 03 '15 at 20:05
  • It is complicated to achieve. JavaScript may not be the best language if you need truly private property access. That said, if closures in JavaScript don't do what you need, chances are you're not thinking about the problem in the "JavaScript way." There's also TypeScript which offers private members, and compiles to JavaScript. – Ethan Brown Jun 03 '15 at 20:39