[是的,我已经阅读了类似问题的几个答案,但没有 真的得到我正在寻找的答案,所以我要问我的问题 反正。]
在下面的代码中,如何将方法setSecret和tellSecret放在Secret的原型中,同时仍然保持对私有实例变量_secret的访问,并产生相同的输出?
我尝试this(请参阅jsbin)将方法放在原型中,但更改了输出。
function Secret() {
// ===== private =====
var _secret;
// ===== public =====
this.setSecret = function (secret) {
_secret = secret;
};
this.tellSecret = function () {
console.log(_secret);
};
}
var secretA = new Secret();
var secretB = new Secret();
secretA.setSecret("AAA");
secretB.setSecret("BBB");
setTimeout(function () {
console.log("Secret A");
secretA.tellSecret();
console.log("Secret B");
secretB.tellSecret();
}, 1000);
// ===== output =====
Secret A
AAA
Secret B
BBB
答案 0 :(得分:6)
简而言之,不应该使用原型方法的私有变量。尝试混合两者需要糟糕的解决方法,并且有更好的选择 这是解释原因。 (这是类似答案的摘录:https://stackoverflow.com/a/21522742/272072)
在JavaScript中,原型方法允许多个实例共享原型方法,而不是每个实例都有自己的方法
缺点是this
是每次调用原型方法时唯一的不同之处。
因此,任何"私人"必须通过this
访问字段,这意味着它们也必须可公开访问。因此,我们所能做的最好的事情就是坚持_private
字段的命名约定。
当您使用闭包创建私有变量时,您无法从原型方法访问它,除非通过this
变量公开。因此,大多数解决方案只是通过方法公开变量,这意味着您以某种方式公开公开它。
_private
字段所以,我认为使用_private
字段最有意义,即使它们仍然是公开的。它使调试更容易,提供透明度,可以提高性能,以及我通常使用的内容
坚持_private
领域的惯例,一切都很顺利
我只是不明白为什么JS开发人员努力使字段真正私有化。
答案 1 :(得分:1)
这个与Alon的答案有关,但是通过实现WeakMap,不会显示识别索引,也不会累积未使用的对象。虽然在效率方面是一个更好的解决方案,但在兼容性方面却不是一个好的答案。 FireFox,Chrome和Node.JS支持WeakMaps,所以我觉得值得一提。
请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap了解详情。
var Secret = (function(){
var secrets=new WeakMap();
function Secret() {
// ===== private =====
secrets.set(this, null);
// ===== public =====
}
Secret.prototype.setSecret = function (secret) {
secrets.set(this, secret);
};
Secret.prototype.tellSecret = function () {
console.log(secrets.get(this));
};
return Secret;
}());
var secretA = new Secret();
var secretB = new Secret();
secretA.setSecret("AAA");
secretB.setSecret("BBB");
setTimeout(function () {
console.log("Secret A", secretA );
secretA.tellSecret();
console.log("Secret B", secretB );
secretB.tellSecret();
}, 1000);
答案 2 :(得分:0)
这是一个令人难以置信的难看的解决方案,你可能不应该使用它,但它的工作原理。基于this answer。
var Secret = (function () {
var instance = 0,
p = [];
function Secret() {
this.i = instance++;
p[this.i] = {};
p[this.i]._secret = null;
}
Secret.prototype.setSecret = function (secret) {
p[this.i]._secret = secret;
};
Secret.prototype.tellSecret = function () {
console.log(p[this.i]._secret);
};
return Secret;
})();
var secret = new Secret();
secret.setSecret("A");
var secret2 = new Secret();
secret2.setSecret("B");
console.log(secret._secret) // => undefined
secret.tellSecret() // => A
secret2.tellSecret() // => B
答案 3 :(得分:0)
试试这个,并告诉我这是你搜索的内容 为了使这个片段更有趣,我向你的对象添加了2个私有属性 (请注意,您的所有私人变量都是私有的)
Error creating foreign key on SectionNumber (check data types)