0

I have a js class that has no public methods. I'm using var's inside a constructor to create these methods and call them with methodName(). Should I use class.prototype.methodName instead and call them within the class with this.methodName()? What's the advantage of either approach? I know prototype methods get copied over to new instances, and thus is faster. But should they be used only for the API of the class?

nuway
  • 2,324
  • 4
  • 27
  • 48
  • if something is the same on each object, it goes in the proto, stuff that's different should be own'd. – dandavis Nov 05 '13 at 23:46
  • 1
    If it has no public members at all then what's point of creating instance(ses) of this type? – HMR Nov 06 '13 at 03:27

1 Answers1

1

JavaScript doesn't have private vairables, thus using a pattern that simulates them causes some overhead (more cpu and memory is needed to run your code). Code with privates can be harder to maintain.

The pattern that simulates private members can be split up in 2 different types:

  1. Instance specific members
  2. Prototype Members

Instance specific could be something like a person's religion and prototype member could be the doSomethingDangerous function. Before religion returns a value you may want to check if the requesting object has access to this private information. The function doSomethingDangerous should not be called directly because you can't be sure that when called from outside Person the right precautions have been taken before doing it.

Methods that can access "private" members are privileged methods. If they need to access instance specific members they need to be in the constructor body (that is where instance specific members are declared). If they need to access prototype specific members they need to be in the same body as where the "private" is declared.

Here is an example:

//constructor for Person
var Person = function(){//<=start body of constructor function
  //to properly use prototype and not cause your code to consume
  // more resources to simulate something that isn't supported
  // in JavaScript "private" variable names usually start with _
  // so other programmers know not to set, get or call this directly
  this._normalPrivate;
  var religion = undefined;//<=instance specific private
  this.religion = function(){//<=privileged function
    console.log(religion);//<=can access private instance here
  }
};
Person.prototype=(function(){//<=start body of function returning object for prototype
  //All person instances share this, it's not instance specific
  var doSomethingDangerous=function(){//<=private prototype
    // doing something dangerous, don't want this to be called directly               
  };
  return {
    doSomething:function(){//<=priviliged method, can access private prototype
      //we cannot access religion because it's defined in a different 
      //  function body
      //make sure we can do something dangerous
      doSomethingDangerous();
    }
  };
}());
Person.prototype.constructor=Person;
Person.prototype.anotherMethod=function(){
  //not a privileged method, cannot access doSomethingDangerous or religion
};

var ben = new Person();

I never use this pattern though because private is only used to indicate to other programmers not to directly access these members. As in the following example you don't want a programmer (including yourself in the future) to do something like:

ben._doSomethingDangerous();

To indicate to other programmers (and future self) that doSomethingDangerous is private you can add an underscore in front of it:

Person.prototype._doSomethingDangerous=function(){...

More on prototype, inheritance, mix ins here https://stackoverflow.com/a/16063711/1641941

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160