0

大家好,我已经读过我所问的问题是不可能的(我想如果考虑到私有领域是通过封闭实现的,为什么会这样)。

(例如:以前我读过那篇文章在原型中访问“私有”变量

所以我想出了一个可能的解决方法。在我的情况下,我希望只能通过原型设置私有属性(称为 __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 编译器中的内联)。

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

4

1 回答 1

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,否则您可能会得到意想不到的结果。

于 2013-12-27T12:13:30.940 回答