0

我有一个类,它有一个带有公共 setter/getter 函数的私有变量:

function Circle(rad) {
    var r = rad;

    this.radius = function(rad) {
        if(!arguments.length) return r;
        r = rad;
        return this;
    }
}

var shape = new Circle(10);
console.log( shape.radius() ); // 10
shape.r = 50;
console.log( shape.radius() ); // 10

我怎样才能复制这个使用Object.prototype?或者,我什么时候想使用闭包而不是Object.prototype?这是我能想到的最接近的,但正如您所看到的,您可以直接更改属性。

function Circle(r) {
    this.r = r;
}

Circle.prototype.radius = function(r) {
    if(!arguments.length) return this.r;
    this.r = r;
    return this;
};

var shape = new Circle(10);
console.log( shape.radius() ); // 10
shape.r = 50;
console.log( shape.radius() ); // 50
4

2 回答 2

4

如果您打算使用原型来存储对象的属性,则可以从任何引用该对象的代码中访问它们。做你想做的事是不可能的。

许多 JS 开发人员所做的只是用前导下划线命名私有属性,以便其他人知道不要乱用它,但除了建议之外,它并没有给你任何真正的保护

使用基于闭包的方法的原因

  • 真正的私人变量,相信没有人会弄乱你的私人

使用原型的原因

  • 使用更少的内存(每个实例都没有闭包)
  • 更易于调试(属性在对象本身上可见)
  • 允许猴子修补

读者:请编辑答案,说明您认为最佳解决方案的原因。

于 2012-06-14T21:48:08.610 回答
0

我觉得你的第一个圈子很奇怪。如果你像这样重写它:

        function Circle(rad) {
            var r = rad;

            this.radius = function(rad) {
                if(rad){r = rad;}
                return r;
            }
        }

我认为它现在符合你的意思。r 是私有的,并且 radius 充当 getter/setter 函数。像这样设置 r:

shape.r = 50;

没有意义,因为您的第一个 Circle 没有属性 r,它只有一个局部范围的变量 r。它应该引发某种错误。

I can't see a way of using prototype in your second version of Circle because the function in the prototype chain wouldn't have access to a variable created in the Circle object. And anyway, in your second version, r is a property of Circle not a privately scoped variable in the function body.

于 2012-06-14T22:02:16.180 回答