大家好,我已经读到了我的要求是不可能的(我想如果考虑通过clousure实现私人领域的原因)。
(例如:之前我已阅读过帖子Access "private" variables in prototype)
所以我致力于一个可能的解决方法。 在我的情况下,我认为私有属性(称为__counter)只能通过原型设置,因为试图访问该“私有”字段的其他人(除了我)可能会破坏我的对象的功能。
function Test(_c) {
var __counter = _c;
this.getCounter = function() {
return __counter;
};
this.increment = function() {
for (var proto in Test.prototype)
if (Test.prototype[proto] == arguments.callee.caller)
return ++__counter;
return undefined;
};
}
Test.prototype.getNext = function() {
return this.increment();
};
var t1 = new Test(1);
alert(t1.getCounter());
alert(t1.getNext());
alert(t1.increment());
alert(t1.getCounter());
我现在的问题是,该解决方案是否可以接受,以及如何改善我注意到的一些性能问题。
我认为为每次调用循环对象原型可能很昂贵(使用散列表而不是?)而且我知道不推荐使用arguments.callee.caller(并打破js编译器中的内联)。
因此排除性能问题(我希望减轻),使用该方法是否具有实际优势,而不是在对象构造函数中定义所有方法? (我知道这种情况很简单,但对于更复杂的情况,只有少数属性必须私有访问,并且有很多方法需要在原型中定义)。
答案 0 :(得分:0)
不,这是不可接受的,因为这段代码很容易破坏你的“修复”:
Test.prototype.myIncrement = function() {
return this.increment();
};
这在原型中定义,因此可以访问this.increment
。 JavaScript允许在运行时修改原型,并在对象的所有实例之间共享原型编辑。
//Test "class"
var t1 = new Test(1);
Test.prototype.myIncrement = function() {
return this.increment();
};
console.log(t1.getCounter());
console.log(t1.getNext());
console.log(t1.myIncrement());
console.log(t1.getCounter());
请记住,JavaScript是在客户端计算机上执行的,因此可以根据所有者的喜好对其进行修改。你可以让某人更难修改你的代码,但这绝不是不可能的。
<强>旁注强>:
我认为为每次调用循环对象原型可能很昂贵(使用散列表而不是?)而且我知道不推荐使用arguments.callee.caller(并打破js编译器中的内联)。
是的,它可能非常昂贵,但在这种情况下(因为原型很小),真正的问题是arguments.caller.callee
。这就是导致性能问题的原因。
最后一件事,当使用for..in
运算符进行循环时,请记住使用hasOwnProperty
,否则可能会产生意外结果。