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

javascript: can I define a "private" variable using prototype?

我想为每个 "instance" 使用一个唯一的私有变量(我希望这是 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)

我看到 solution

this would mean duplicating the function on every instance, and the function lives on the instance, not on the prototype.

另一位作者说

That's still not quite traditional classly Javascript, which would define the methods only once on Account.prototype.

那么,有没有解决方案

?

问题是每次调用构造函数时您都在替换原型函数。

使用旧式基于闭包的隐私,您无法从原型方法访问 "private" 成员,因为只有在关闭它们的构造函数中定义的函数才能使用它们。所以你最终为每个实例重新制作函数(这并不像听起来那么糟糕,但也不是很好)。

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.

上的属性