繁体   English   中英

javascript:我可以使用原型定义一个“私有”变量吗?

[英]javascript: can I define a “private” variable using prototype?

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

我看到了一个解决方案,但是

这意味着在每个实例上复制 function,并且 function 存在于实例上,而不是原型上。

另一位作者说同样的解决方案

这仍然不是很传统的经典 Javascript,它只会在Account.prototype 上定义一次方法。

那么,有没有解决方案

  • 每个实例都可以有唯一的secret
  • secret仅可用于构造函数中定义的方法,并且
  • 函数不会为每个实例重复

?

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

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

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可以访问的地方。

您也可以在不使用WeakMap语法的情况下使用class ,但是如果您正在创建具有关联原型的构造函数,则classfunction Example和分配给Example.prototype上的属性更简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM