The main problem
When you return a non-primitive value from a constructor function, that non-primitive value is returned rather than the default returned instance you would expect when invoking it with the new
keyword.
E.g.
function A() { return {}; }
new A() instanceof A; //false
Therefore you could simply change your code to something like:
RB.Orange = function() {
// Private
function makeOrangeJuice() {
console.log("Orange has been squeezed.");
}
this.getName = function () {
return 'Orange';
};
//priviledged function which uses a private member
this.someOtherFunction = function () {
makeOrangeJuice();
};
};
Some inefficiencies in your code
Why not using the prototype
?
Functions that aren't priviledged should not be declared within the constructor function. In other words, functions that do not access private variables should not be created in the constructor function because they do not have to and it's extremely inefficient to do so. Why? Because a new function is being created everytime the constructor is called.
Instead you should make use of the Constructor.prototype
to share your public functions between all instances.
E.g.
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function () {
console.log('My name is ' + this.name);
};
new Person('Foo Bar').sayName();
Use Object.create
rather than new
for inheritance when possible.
Most inheritance patterns using the new
keyword were done this way because the language was lacking another way of setting up the prototype chain of an object, but now that we have Object.create
, your should use it. Using the new
keyword for inheritance the way you did has some undesired side-effects like running the constructor function. There are ways to avoid these side effects by using an intermediate empty function but why not simply use Object.create
?
E.g. (based on the above example)
function BadPerson(name) {
//call parent constructor
Person.call(this, name + ' the bad');
}
BadPerson.prototype = Object.create(Person.prototype);
BadPerson.prototype.constructor = BadPerson; //fix constructor
Private functions can also be shared!
Note that private functions that do not access private variables can also be shared. You can make use of the module pattern to create a scope for them.
E.g.
var Person = (function () {
//private function used in a functionnal style
function _validateName(name) {
console.log('Validating the name in functionnal style');
}
//private function used in an OO style
function _validateNameOO() {
console.log('Validating the name in a OO style');
}
function Person(name) {
this.name = name;
}
Person.prototype.validateNameBothWays = function () {
_validateName(this.name);
_validateNameOO.call(this);
};
return Person;
})();
new Person().validateNameBothWays();