0

In JavaScript, classes are usually emulated through constructors. However, I'm curious as to how one can create an encapsulated class, i.e. a class that keeps some of it's members private.

The commonly seen way of creating a 'class' is as follows:

function MyClass(parameter) {
    this.value = parameter;
}

MyClass.prototype.myPublicFunction = function() {
    console.log("About to run private function.");
    myPrivateFunction();
};

MyClass.prototype.myPrivateFunction = function() {
    ...
};

As you can see, in this example myPrivateFunction is actually public. One approach I've seen to solve this problem is the following:

function MyClass(parameter) {
    this.value = parameter;

    this.myPublicFunction = function() {
        console.log("About to run private function.");
        myPrivateFunction.call(this);
    }

    function myPrivateFunction() {
        ...
    }
}

This works; myPrivateFunction is inaccessible from the outside. But this approach has a problem - all functions in this 'class' are going to be copied across instances, instead of shared through the prototype. Also using privateFunction.call(this) everywhere isn't awesome.

Same goes for non-function members. How can I define a private instance-member in a class? What is the best and what is the most common approach? Is it acceptable to simply rely on a naming convention (such as beginning private function names with a _)?

3
  • 1
    There is basically no way to do this properly in ES5. You can do it with WeakMap in ES6 but that would mean you can only support very recent browsers. Commented Jan 30, 2015 at 15:05
  • James - Could you post a example with it (an answer?). I am not fully aware of the features in ES6 and got a bit curious about how a WeakMap could be used to deal with this. Guess I am growing rusty =) Commented Jan 30, 2015 at 15:45
  • 1
    Maybe the following will help, it has a protected instance specific pattern: stackoverflow.com/a/21800194/1641941 Commented Jan 30, 2015 at 15:51

1 Answer 1

2

You could create a scope to hide you private functions with an auto executing function.

Like:

(function(){
    function myPrivateFunction(arg_a, arg_b) {
        /* ... */
        console.log("From priv. function " + this.value);
    }
    window.MyClass = function(parameter) {
        this.value = parameter;

        this.myPublicFunction = function() {
            console.log("About to run private function.");
            myPrivateFunction.call(this, 'arg_a', 'arg_b');
        }

    }
})();

But then you need to use MyClass only after it is declared since now it is an function expression and not a function statement, but all instances of MyClass will share the same instance of myPrivateFunction. but you will need to use Function.prototype.call (as in myPrivateFunction.call(this, 'arg_a', 'arg_b'); to get the value of this keyword to match your instance. If you do just myPrivateFunction('arg_a, 'arg_b'); the keyword this will point to the global object (window on browsers) or null if 'strict mode' is enabled.

Just a note: In my own code I don't do this but rely on naming conventions like MyClass.prototype._myPrivateFunction = function(){}; when not using some framework.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.