我想为每个"实例"使用一个唯一的私有变量(我希望这是Javascript中正确的术语(,但两个实例似乎都使用相同的私有变量。
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)
我看到了一个解决方案,但是
这意味着在每个实例上复制函数,并且 函数存在于实例上,而不是原型上。
另一位作者说同样的解决方案
这仍然不是很传统的经典Javascript,它只会在Account.prototype上定义一次方法。
那么,有没有解决方案在哪里
- 每个实例都可以具有唯一的
secret
值 secret
只能对构造函数中定义的方法访问 和- 函数不会为每个实例重复
?
问题是每次调用构造函数时都要替换原型函数。
使用基于闭包的旧式隐私,您无法从原型方法访问"私有"成员,因为只有构造函数中定义的函数才能使用它们。所以你最终会为每个实例重新制作函数(这并不像听起来那么糟糕,但也不是很好(。
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;
};
}
为您提供两种选择:
1( 使用像 Babel、class
语法和私有字段这样的转译器(可能在 ES2021 中,现在通过转译使用了相当长的时间(:
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(使用包含机密信息的WeakMap
(ES2015+(
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"
你把secrets
放在只有Example
才能访问的地方。
您也可以在不使用class
语法的情况下使用WeakMap
,但如果要使用关联的原型创建构造函数,则class
比function Example
和分配给Example.prototype
上的属性更简单。