Skip to content

Instantly share code, notes, and snippets.

@n1k0
Last active December 19, 2015 13:49
Show Gist options
  • Select an option

  • Save n1k0/5964887 to your computer and use it in GitHub Desktop.

Select an option

Save n1k0/5964887 to your computer and use it in GitHub Desktop.
Two alternatives to bring private methods to JavaScript. Prefer method 2.
(function(exports) {
function Universe() {
this.partialAnswer = 21;
}
exports.Universe = Universe;
// private methods
var privatePrototype = {
_computeAnswer: function() {
return this.partialAnswer * 2;
}
};
// public API
Universe.prototype = {
getAnswer: function() {
return privatePrototype._computeAnswer.call(this);
}
};
})(this);
console.log(new Universe().getAnswer()); // 42
(function(exports) {
function Universe() {
this.partialAnswer = 21;
}
exports.Universe = Universe;
// private methods
function _computeAnswer() {
return this.partialAnswer * 2;
}
// public API
Universe.prototype = {
getAnswer: function() {
return _computeAnswer.call(this);
}
};
})(this);
console.log(new Universe().getAnswer()); // 42
@DavidBruant
Copy link

This only works if the private method acts on public state.

@n1k0 On Twitter:

well I'm not sure because of the .call(this) binding… did I miss smthg? please comment the gist with code :)

I'm not sure what you mean. How do you make per-instance private state in JavaScript? Please answer with code ;-)
Hint: it's not possible; hence symbols in ES6 (but I can't find one good reference resource on the topic :-/ ). The spec on this topic has been moving a lot. One of the most promising approach for private state is relationships in my opinion. A good share of TC39 disagrees apparently...

@fedir
Copy link

fedir commented Jul 10, 2013

is it really private ?

private1.js

console.log(privatePrototype._computeAnswer.call(new Universe)); // 42

@n1k0
Copy link
Author

n1k0 commented Jul 10, 2013

@DavidBruant ok I understand what you mean, but I don't want private state here, just private methods (functions if you like it more), which if I'm correct don't carry state in these very examples.

But if I want to handle private state, I'd probably turn the private prototype in to a new constructor for each public instance to carry its own private proto. Hope it makes sense.

@fedir updated the gist to highlight the purpose

@n1k0
Copy link
Author

n1k0 commented Jul 10, 2013

@DavidBruant ok now I get what you mean, if I create a new constructor for each public instance to carry its own private proto, it wouldn't be private anymore because publicly attached to the public API. Makes sense. Can't wait for ES6 to address this :)

@fedir
Copy link

fedir commented Jul 10, 2013

Why You call it private ? Better to call it hidden, masked methods, as they could be executed directly.

private2.js

console.log(_computeAnswer.call(new Universe())); // 42

@n1k0
Copy link
Author

n1k0 commented Jul 10, 2013

@fedir nope, hence the IIFE:

(function(exports) {
  function Universe() {  
    this.partialAnswer = 21;
  }
  exports.Universe = Universe;

  // private methods
  function _computeAnswer() {
    return this.partialAnswer * 2;
  }

  // public API
  Universe.prototype = {
    getAnswer: function() {
      return _computeAnswer.call(this);
    }
  };
})(this);

console.log(new Universe().getAnswer()); // 42

console.log(_computeAnswer.call(new Universe())); // ReferenceError: _computeAnswer is not defined

@DavidBruant
Copy link

BruanT avec un T ! (sinon, je reçois pas de notif ;-) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment