JavaScript:我可以使用原型定义一个"private"变量吗?



我想为每个"实例"使用一个唯一的私有变量(我希望这是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,但如果要使用关联的原型创建构造函数,则classfunction Example和分配给Example.prototype上的属性更简单。

最新更新