I have defined pure objects in JS which expose certain static methods which should be used to construct them instead of the constructor. How can I make a constructor for my class private in Javascript?
var Score = (function () {
// The private constructor
var Score = function (score, hasPassed) {
this.score = score;
this.hasPassed = hasPassed;
};
// The preferred smart constructor
Score.mkNewScore = function (score) {
return new Score(score, score >= 33);
};
return Score;
})();
Update: The solution should still allow me to test for x instanceof Score
. Otherwise, the solution by @user2864740 of exposing only the static constructor works.
How can I make a constructor for my class private in Javascript? var Score = (function () { // The private constructor var Score = function (score, hasPassed) { this. score = score; this.
Yes, we can declare a constructor as private. If we declare a constructor as private we are not able to create an object of a class. We can use this private constructor in the Singleton Design Pattern.
Java allows us to declare a constructor as private. We can declare a constructor private by using the private access specifier. Note that if a constructor is declared private, we are not able to create an object of the class. Instead, we can use this private constructor in Singleton Design Pattern.
In a JavaScript class, to declare something as “private,” which can be a method, property, or getter and setter, you have to prefix its name with the hash character “#”.
One can use a variable (initializing
) inside a closure which can throw an error if the constructor was called directly instead of via a class method:
var Score = (function () {
var initializing = false;
var Score = function (score, hasPassed) {
if (!initializing) {
throw new Error('The constructor is private, please use mkNewScore.');
}
initializing = false;
this.score = score;
this.hasPassed = hasPassed;
};
Score.mkNewScore = function (score) {
intializing = true;
return new Score(score, score >= 33);
};
return Score;
})();
Is there a solution which will allow me to say
x instanceof Score
?
Yes. Conceptually, @user2864740 is right, but for instanceof
to work we need to expose (return
) a function instead of a plain object. If that function has the same .prototype
as our internal, private constructor, the instanceof
operator does what is expected:
var Score = (function () {
// the module API
function PublicScore() {
throw new Error('The constructor is private, please use Score.makeNewScore.');
}
// The private constructor
var Score = function (score, hasPassed) {
this.score = score;
this.hasPassed = hasPassed;
};
// Now use either
Score.prototype = PublicScore.prototype; // to make .constructor == PublicScore,
PublicScore.prototype = Score.prototype; // to leak the hidden constructor
PublicScore.prototype = Score.prototype = {…} // to inherit .constructor == Object, or
PublicScore.prototype = Score.prototype = {constructor:null,…} // for total confusion :-)
// The preferred smart constructor
PublicScore.mkNewScore = function (score) {
return new Score(score, score >= 33);
};
return PublicScore;
}());
> Score.mkNewScore(50) instanceof Score
true
> new Score
Error (…)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With