4

I've found similar questions, but none that answer this explicitly, so I hope someone can help clear this up for me.

In regards to constructor functions, I am trying to figure if variables and functions are, by default, public or private.

For example, I have this sample constructor with these properties:

function Obj() {
  this.type = 'object';
  this.questions = 27;
  this.print = function() {
    console.log('hello world');
  }
}

I can call these properties as such:

var box = new Obj();
box.type; // 'object'
box.print(); // 'hello world'

It seems to me like both functions and variables are public by default. Is that right? Or, if functions inside constructors are private... can they only take private variables as parameters?

Thank you.

Jose
  • 4,880
  • 8
  • 27
  • 49
  • Not 100% clear what you're asking. If you can access these variables and functions, surely they are public? – sg.cc Nov 25 '15 at 03:33
  • https://carldanley.com/js-revealing-module-pattern/ – Phix Nov 25 '15 at 03:36
  • [Javascript Variable Scope](http://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/) can be a complicated thing to fully understand. "`In many programming languages, you’ll hear about public and private scope, in JavaScript there is no such thing. We can, however, emulate public and private scope through things like Closures."` – Jake Nov 25 '15 at 03:36
  • 1
    Statements like "*…both functions and variables are public…*" make me think that you're a little confused between *variables* and *properties*, or maybe you're just not being precise with your expression. Either way, make sure you fully understand the difference. – RobG Nov 25 '15 at 03:54

1 Answers1

6

All properties on an instance in Javascript (things you assign with this.property = xxx) are public - whether they are assigned in the constructor or elsewhere.

If you use Object.defineProperty() a given property may be made read-only or may be a getter or setter, but they are all visible to the outside world.

Javascript does not have a built-in language feature for "private" properties. You can use local variables or local functions within the constructor as private, but they are only available to code or methods defined within the constructor.

So, in your example:

function Obj() {
  this.type = 'object';
  this.questions = 27;
  this.print = function() {
    console.log('hello world');
  }
}

All the properties type, questions and print are publicly accessible.


One technique to create "private" methods is to define a local function within the constructor like this:

function Obj() {
  var self = this;

  // this is private - can only be called from within code defined in the constructor
  function doSomethingPrivate(x) {
      console.log(self.type);
  }

  this.type = 'object';
  this.questions = 27;
  this.print = function(x) {
    doSomethingPrivate(x);
  }
}

Here's one of the more common references on using a constructor closure to create private access: http://javascript.crockford.com/private.html.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • This clears it up perfectly. Thank you! – Jose Nov 25 '15 at 04:26
  • Please use the term "instance property" instead of "instance variable". Otherwise it sounds like you meant a variable :-) – Bergi Nov 25 '15 at 05:14
  • @Bergi - I modified the phrasing so the OP isn't confused, though "instance variable" seems to have the appropriate meaning as described [here](http://javascript.crockford.com/private.html) and [here](https://en.wikipedia.org/wiki/Instance_variable). – jfriend00 Nov 25 '15 at 05:20
  • @jfriend00: OK, but I'd argue that terminology is restricted to class-ical programming languages. JS doesn't distinguish between (non-function) "variables" and "methods" either. "instance member" sounds more fitting to describe both the OOP concept and JS object properties. – Bergi Nov 25 '15 at 05:26