Javascript访问私有字段表单原型(解决方法)

时间:2013-12-27 11:57:56

标签: javascript performance closures prototyping

大家好,我已经读到了我的要求是不可能的(我想如果考虑通过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编译器中的内联)。

因此排除性能问题(我希望减轻),使用该方法是否具有实际优势,而不是在对象构造函数中定义所有方法? (我知道这种情况很简单,但对于更复杂的情况,只有少数属性必须私有访问,并且有很多方法需要在原型中定义)。

1 个答案:

答案 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,否则可能会产生意外结果。