I am sure that this must be a pretty common question but after scouring the internets for several hours, I have not found an answer. Here is the question:
Suppose that
It's not possible. If you need access to private variables/functions, you must use privileged (helper) functions.
It sometimes is possible to use helper functions in a local closure scope instead of private helper functions (in the constructor scope), which would be accessible from prototype functions. See Alex Wayne's or Raynos' answers for that.
You said:
I cannot make the eat function a privaliged function because in order for prototype inheritance to work it needs to be part of the prototype.
Why not?
MammalPrototype = {
eat: function() {},
sleep: function() {}
};
function Dog(color) {
...
this.eat = function() {
... // using private functions
MammalPrototype.eat.call(this, options) // ?
};
};
Dog.prototype = Object.create(MammalPrototype); // inherit from an object
new Mammal()
is OK when Mammal really is only a empty function. See https://stackoverflow.com/a/5199135/1048572 for how this works. The shim proposed there is of course not what a native implementation does, but it is exactly what we need here. Do not create a instance just to inherit from it!
Dog.prototype.sleep = function() {
...
};
function Dalmatian() {
Dog.call(this, "black.white");
...
}
Dalmatian.prototype = Object.create(Dog.prototype); // sic
Dalmatian.prototype.xyz = function() {};
To call the super constructor on this
means to receive all privileged methods, and their functionality. You will need to do this if you are using private variables and/or functions in "classes" you inherit from, otherwise all calls to inherited privileged functions will affect only the one instance you've set your prototype
to.
Define your Dog
"class" in a closure. Then you can have shared priveliged functions. Just know you will have to be careful about this
binding properly when you call it.
var Dog = (function() {
function Dog() {};
// Common shared private function, available only to Dog.
var privateHelper = function() { ... };
Dog.prototype = new Mammal();
Dog.prototype.eat = function() {
privateHelper()
// Or this if the helper needs to access the instance.
// privateHelper.call(this);
...
};
return Dog;
})();
A function on a prototype is still just a function. So follows the same scope and closure access rules as any another function. So if you define your entire Dog
constructor and prototype and a secluded island of scope that is the self executing function, you are welcome to share as much as you like without exposing or polluting the public scope.
This is exactly how CoffeeScript classes compile down to JS.
When an object (child object) inherits from another object (parent object) how should children methods use helper functions and is it possible to make these private?
You need some layers of abstraction to achieve what you want: Live Example
Uses klass
var Mammal = klass(function (privates) {
privates.local_helper = function () {
console.log("local_helper invoked");
}
return {
constructor: function () {
console.log("mammal constructed");
privates(this).caneat = true;
},
eat: function () {
privates.local_helper();
console.log("mammal eat");
},
sleep: function () {
console.log("mammal sleep");
}
};
});
var Dog = klass(Mammal, function (privates, $super) {
return {
constructor: function () {
$super.constructor.call(this);
console.log("dog constructed");
},
eat: function () {
$super.eat.call(this);
privates.local_helper();
console.log("dog eat");
console.log(privates(this).caneat);
}
};
});
var dog = new Dog();
dog.eat();