2

I want to be able to create an object in Javascript that has public methods which can access the object's private members. However, I've heard that there's overhead in declaring public methods every time an object is created, so I'd prefer to avoid that overhead. So, for example, this code would do what I want:

function createMyObject(parameter) { var that = {}; var privateVariable, privateMethod = function () { return 1; }; that.publicVariable = 0; that.publicMethod = function () { privateVariable = privateMethod(); } return that; } 

But everytime someone calls createMyObject, it has to create functions to set the public methods. If instead I do this:

function MyClass(parameter) { var privateVariable, privateMethod = function () { return 1; }; this.publicVariable = 0; } MyClass.prototype.publicMethod = function () {}; 

Here, I can avoid having to create new functions to set public methods everytime an object is constructed, but those public methods can't access the object's private members.

Is there some way to avoid the overhead of having to create new functions for public methods everytime an object is constructed, but also be able to let them have access to private members?

1
  • You can use a self-invoking function to hide your 'private' functions, but you can't create private variables that are not shared amongst instances. Commented Oct 4, 2013 at 0:17

2 Answers 2

3

No, you can't.

A public method which is able to access private variables, is called privileged method.

From Private Members in JavaScript, by Douglas Crockford:

A privileged method is able to access the private variables and methods, and is itself accessible to the public methods and the outside. It is possible to delete or replace a privileged method, but it is not possible to alter it, or to force it to give up its secrets.

Privileged methods are assigned with this within the constructor.

Then, you can't declare privileged methods using the prototype.

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

Comments

0

Using new Javascript features you can have truly private members. Basically you can use WeakMap to hide your members.

This is supported in Firefox and behind the "Experimental Javascript" flag in Chromium.

var MyClass = (function(){ var privmap = new WeakMap; // This holds our private members. Keep it secret. function MyClass(){ var priv = {}; privmap.set(this, priv); // Add your private object for this instance. this.notsec = "Anyone can access this!"; priv.secret = "Only code in this closure can see this!"; } MyClass.prototype.secret = function MyClass_secret() { var priv = privmap.get(this); // Get our private object. return priv.secret; // Retrieve. } return MyClass; })(); var o = new MyClass; console.log(o.secret()); //-> Only code in this closure can see this! 

By adding one line to the beginning of every function you can return your private object. I like to call it priv so that public members go on this and private on priv, nice and consistent.

This has the nice advantage that you only have a single instance of every method, instead of creating a closure for each instance.

1 Comment

I cannot tell if this is different from how Crockford goes about it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.