8

is there a way in JavaScript to inherit private members from a base class to a sub class?

I want to achieve something like this:

function BaseClass() {
  var privateProperty = "private";

  this.publicProperty = "public";
}

SubClass.prototype = new BaseClass();
SubClass.prototype.constructor = SubClass;

function SubClass() {
  alert( this.publicProperty );   // This works perfectly well

  alert( this.privateProperty );  // This doesn't work, because the property is not inherited
}

How can I achieve a class-like simulation, like in other oop-languages (eg. C++) where I can inherit private (protected) properties?

Thank you, David Schreiber

david.schreiber
  • 3,851
  • 2
  • 28
  • 46
  • This pattern does not add a private property. It only adds a local variable called privateProperty in the BaseClass function. – erikkallen Nov 28 '09 at 17:36
  • 1
    see http://stackoverflow.com/questions/1437712/how-to-override-private-variable-in-javascript/1438592#1438592 for my opinion on such language bastardization; learn the semantics of JS instead of trying to emulate C++ – Christoph Nov 28 '09 at 17:43

5 Answers5

14

Using Douglas Crockfords power constructor pattern (link is to a video), you can achieve protected variables like this:

function baseclass(secret) {
    secret = secret || {};
    secret.privateProperty = "private";
    return {
        publicProperty: "public"
    };
}

function subclass() {
    var secret = {}, self = baseclass(secret);
    alert(self.publicProperty);
    alert(secret.privateProperty);
    return self;
}

Note: With the power constructor pattern, you don't use new. Instead, just say var new_object = subclass();.

Dau
  • 8,578
  • 4
  • 23
  • 48
Magnar
  • 28,550
  • 8
  • 60
  • 65
  • Thank you very much! The link to the power constructor pattern video helped me very much. This was exactly what I was looking for. Now I understand that there is much more for me to learn about JS and objects :-) – david.schreiber Nov 29 '09 at 15:57
  • 1
    The link has changed; here's the new one: http://www.yuiblog.com/blog/2006/11/27/video-crockford-advjs/ (The original link was to part 1) – Matt Browne Dec 01 '12 at 19:25
  • 2
    Shouldn't `secret.privateProperty` be `secret.protectedProperty` and then private would be something like `var privateProperty`? – sabgenton Sep 30 '15 at 00:24
  • If you want to use the word protected in that context I mean. – sabgenton Sep 30 '15 at 00:27
  • There is a problem with that solution: You do not add protected members within the subclass here and exatly there the problems arise, because you have only one shared object for protected members. Normally you can have protected members in the baseclass and seperate protected members in the subclass. But anyway nice try ;) – Ini Jul 20 '18 at 13:37
3

Mark your private variables with some kind of markup like a leading underscore _ This way you know it's a private variable (although technically it isn't)

this._privateProperty = "private";
alert( this._privateProperty )
Andris
  • 27,649
  • 4
  • 34
  • 38
0

This isn't possible. And that isn't really a private property - it's simply a regular variable that's only available in the scope in which it was defined.

James
  • 109,676
  • 31
  • 162
  • 175
0

That can't be done, but you could delete the property from the class prototype so that it is not inherited:

SubClass.prototype.privateProperty  = undefined;

That way it won't be inherited, but you need to do that for every "private" property in your base class.

Daniel Rodriguez
  • 1,443
  • 12
  • 19
0

Just for reference if someone finds that today (October 2019) We can implement private properties in javascript using WeakMap()

const _privateProperty = new WeakMap();

class BaseClass {
    constructor(){
        this.publicProperty = 'public';
       _privateProperty.set(this, 'private');
    }
}

module.exports = BaseClass;

Inherits the BaseClass

const BaseClass = require('./BaseClass')

class ChildClass extends BaseClass{
   constructor(){
      super()
   }
}

This way your child class will inherit all the public properties from the BaseClass but the private ones.

Now, I am not sure whether one should take this approach but you can read the private properties from your parent class through your child class this way:

const _privateProperty = new WeakMap();

class BaseClass {
    constructor(){
        this.publicProperty = 'public';
       _privateProperty.set(this, 'private');
    }
    //Public method
    readProperties(){
      const property.private = _privateProperty.get(this);
      return property;
   }
}

module.exports = BaseClass;

Child Class

const BaseClass = require('./BaseClass')

class ChildClass extends BaseClass{
   constructor(){
      super()
   }
   //Public Method
   showProperties(){
      super.readProperties().private
   }
}

const properties = new ChildClass()
properties.showProperties()

Community
  • 1
  • 1
EAzevedo
  • 751
  • 2
  • 17
  • 46