I want to use a unique private variable for each "instance" (I hope that this is the right term in Javascript), but both instances appear to use the same private variable.
func = function(myName)
{
this.name = myName
secret = myName
func.prototype.tellSecret = function()
{ return "the secret of "+this.name+" is "+secret
}
}
f1 = new func("f_One")
f3 = new func("f_3")
console.log(f3.tellSecret()) // "the secret of f_3 is f_3" OK
console.log(f1.tellSecret()) // "the secret of f_One is f_3" (not OK for me)
I saw a solution but
this would mean duplicating the function on every instance, and the function lives on the instance, not on the prototype.
Another author says about the same solution
That's still not quite traditional classly Javascript, which would define the methods only once on Account.prototype.
So, is there a solution where
secret
secret
is only accessible for methods that are defined in the constructor
and?
The problem is that you're replacing your prototype function each time the constructor is called.
With old-style closure-based privacy, you can't access "private" members from prototype methods, because only functions defined in the constructor closing over them can use them. So you end up remaking the functions for each instance (which isn't as bad as it sounds, but isn't great).
function Example(name) {
this.name = name;
var secret = name; // Using `var` here on the basis this is ES5-level code
// This can't be a prototype function
this.tellSecret = function() {
return "the secret of " + this.name + " is " + secret;
};
}
Two options for you:
1) Use a transpiler like Babel, class
syntax, and private fields (likely to be in ES2021, in use for a fair bit time now via transpiling):
class Example {
#secret;
constructor(name) {
this.name = name;
this.#secret = name;
}
tellSecret() {
return "the secret of " + this.name + " is " + this.#secret;
}
}
const f1 = new Example("f_One");
const f3 = new Example("f_3");
console.log(f3.tellSecret()) // "the secret of f_3 is f_3"
console.log(f1.tellSecret()) // "the secret of f_One is f_One"
2) Use a WeakMap
(ES2015+) containing the secret information
const secrets = new WeakMap();
class Example {
constructor(name) {
this.name = name;
secrets.set(this, name);
}
tellSecret() {
return "the secret of " + this.name + " is " + secrets.get(this);
}
}
const f1 = new Example("f_One");
const f3 = new Example("f_3");
console.log(f3.tellSecret()) // "the secret of f_3 is f_3"
console.log(f1.tellSecret()) // "the secret of f_One is f_One"
You put secrets
where only Example
has access to it.
You can use a WeakMap
without using class
syntax too, but if you're creating constructor functions with associated prototypes, class
is simpler than function Example
and assigning to properties on Example.prototype
.