Hjosef
Hjosef

Reputation: 37

Private methods within constructor (Javascript, bad idea?)

When we declare a method within the prototype object we simply have a single location in memory in which we can later invoke methods from however using the idea of private methods we will re-create the methods in memory every single time we create a new child.

Just for visual sake have a look at both structures below:

function Person(firstname, lastname){
  this.firstname = firstname,
  this.lastname = lastname
}

Person.prototype.getFullName = function() {
  return this.firstname + ' ' + this.lastname;
}

var ham = new Person('Hamoodi', 'Josef');

Okay so the above code creates a method and stores it within our prototype object, great stuff.

function Person(firstname, lastname){
  this.firstname = firstname,
  this.lastname = lastname,

    this.getFullName = function() {
      return this.firstname + ' ' + this.lastname;
    }
}

from what I've understood (please correct me if i'm wrong) this is how i create a private method, this just seems like a bad idea if we need to create many children, or am i just missing the point?

Any thoughts?

Upvotes: 2

Views: 320

Answers (2)

spmurrayzzz
spmurrayzzz

Reputation: 136

One way to get private methods in a given module, is to just define them in a scope unreachable by other API consumers.

Note that this can make unit testing a challenge, though in Node.js you can use something like rewire to gain access to the private function.

function Person(firstname, lastname){
  this.firstname = firstname,
  this.lastname = lastname,

  getFullName.call( this );
}

function getFullName() {
  return this.firstname + ' ' + this.lastname;
}

Upvotes: 0

Patrick
Patrick

Reputation: 6958

There is nothing private about the way you defined getFullName function. It will be available on any Person instance, and copied across each instance. This is why methods are put on the prototype of the Constructor so that they are shared across instances.

If you were to truly have a private function inside your constructor, it would look something like this:

function Person(firstname, lastname){
  // bind the function to this instance
  var getFullName = (function () {
      return this.firstname + ' ' + this.lastname;
  }).bind(this);

  this.firstname = firstname;
  this.lastname = lastname;
  // call private function and set property
  this.fullName = getFullName();
}

This again suffers the negative impact that each instance will create its own copy of this private method (but at least this time its scope is actually private).

Private methods usually make sense as "utility" type methods. For example, consider the following:

// your javascript file
(function (global) {

    // private scope
    var id = 0,
    getId = function () {
        return ++id;
    };

    function Person(firstname, lastname) {
        // call private method to get id
        this.id = getId();
        this.firstname = firstname;
        this.lastname = lastname;
    }

    // expose globally
    global.Person = Person;

}(window));

Now when somebody uses your API to create a new person, it uses the privately available getId function to assign a unique id to that person. Hopefully this demonstrates when you would think about using private state vs. methods publicly available on the prototype.

Upvotes: 3

Related Questions