In JS, regardless of whether we use class inheritance or composition we have to make a trade-off between encapsulation and memory conservation. Since memory is cheap and abundant, in most cases, encapsulation is the correct choice.
If you want true data privacy in JS, you must use a closure, and if you use a closure, the privileged methods must be defined in the same function scope.
That means those functions will indeed be recreated for each instance, because the definition of a closure is a function bundled with its lexical scope. That’s how data privacy works in JS. If you want to use true data privacy with
class, you must define the privileged method inside the constructor, which also creates a new instance of that function for each object instance.
Some people have begun to use symbols for data privacy in JS, but symbols can be introspected, and are not truly private in the same sense that closures are. Symbols are also not as well understood or supported as closures.