How can I create a JavaScript private methods with a public method like:
function Restaurant() {}
Restaurant.prototype.buy_food = function() {
// something here
}
Restaurant.prototype.use_restroom = function() {
// something here
}
This allows users of my class to call:
var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();
Now, I want to define a private method that can be called by the buy_food and use_restroom methods but cannot be accessed externally.
For instance, I want this to work:
Restaurant.prototype.use_restroom = function() {
this.private_stuff();
}
But I want to prevent this from working:
var r = new Restaurant();
r.private_stuff();
How do I define private_stuff as a private method in JavaScript so that it can only be used internally within the class but not accessed publicly?
If you’re looking to make private_stuff
inaccessible externally, closures are a simple and effective way in JavaScript to create private methods. Here’s how you can do it inside the constructor function, which keeps private_stuff
out of the prototype and invisible to any outside code._
function Restaurant() {
// Private method
var private_stuff = function() {
console.log("Doing private stuff");
};
this.buy_food = function() {
private_stuff();
console.log("Buying food");
};
this.use_restroom = function() {
private_stuff();
console.log("Using restroom");
};
}
var restaurant = new Restaurant();
restaurant.buy_food(); // Works
restaurant.use_restroom(); // Works
// restaurant.private_stuff(); // Error: private_stuff is not a function
This approach with closures is perfect for keeping private_stuff
inaccessible, making it one of the cleaner ways to implement javascript private methods
in constructor functions.
Now, if you’re using modern JavaScript (ES6 and beyond), the #
syntax makes it possible to create truly private fields and methods in classes. Using #
keeps private_stuff
accessible only within the class context. Here’s an example:_
class Restaurant {
// Private method
#private_stuff() {
console.log("Doing private stuff");
}
buy_food() {
this.#private_stuff();
console.log("Buying food");
}
use_restroom() {
this.#private_stuff();
console.log("Using restroom");
}
}
let restaurant = new Restaurant();
restaurant.buy_food(); // Works
restaurant.use_restroom(); // Works
// restaurant.#private_stuff(); // Syntax Error: Private field '#private_stuff' must be declared in an enclosing class
In ES2022, this #
syntax really is a clean solution if you’re working with classes and want clear-cut javascript private methods
.
Another approach worth considering, especially if you’re working across different instances of an object, is using a WeakMap
to handle private methods. This pattern ensures that private methods remain accessible only to internal functions while being entirely hidden from public access._
const privateStuff = new WeakMap();
function Restaurant() {
// Set up private method in WeakMap
privateStuff.set(this, function() {
console.log("Doing private stuff");
});
this.buy_food = function() {
privateStuff.get(this)();
console.log("Buying food");
};
this.use_restroom = function() {
privateStuff.get(this)();
console.log("Using restroom");
};
}
var restaurant = new Restaurant();
restaurant.buy_food(); // Works
restaurant.use_restroom(); // Works
// restaurant.private_stuff(); // Error: private_stuff is not defined
This WeakMap
approach is a solid alternative for javascript private methods
, especially when you need private access across multiple instances without modifying the class itself.