【问题标题】:Efficiency issue with closure based objects基于闭包的对象的效率问题
【发布时间】:2011-03-03 12:51:08
【问题描述】:

在 Javascript 中定义类的一种方法是使用闭包和对象字面量。例如,考虑一个圆圈:

var circle = function(radius) {
    var radius = radius;
    return {
        area: function() { 
            return Math.PI*(radius*radius); 
        }
    }
}

然后可以使用保持封装的内部变量来实例化圆对象:

c = circle(1);
c.area(); // Returns pi
c.radius; // Returns undefined

不幸的是,使用这种方法,如果我要创建多个圆,则会为每个实例复制 area 函数。这是通常使用原型的地方:

var Circle = function(radius) {
    this.radius = radius;
}
Circle.prototype.area = function() { 
    return Math.PI*(this.radius*this.radius); 
};

现在的问题是不能将变量声明为私有的:

c = new Circle(1); 
c.area(); // Returns pi 
c.radius; // Returns 1

有谁知道我将如何充分利用两者?效率是一个问题,所以宁愿避免第一种方法的当前公式,我正在为公共 API 编写,所以不希望用户访问内部变量/方法。提前谢谢...

【问题讨论】:

    标签: javascript prototype closures


    【解决方案1】:

    这个怎么样:

    function Circle(radius) {
        this.getRadius = function() { return radius; }
    }
    
    Circle.prototype.area = function() {
        var r = this.getRadius();
        return Math.PI * r * r; 
    };
    

    现在Circle 伪类的每个实例都有两个方法:

    • area 继承自原型,因此使其成为公共方法
    • getRadius 分配给实例对象,从而使其成为实例方法

    radius 的值仍然可以通过getRadius 检索。但是,如果getRadius 可以确定它是否是从Circle.prototype 方法中调用的,并且如果是则只返回radius 值,那么这将解决它,但我不确定是否可以这样做。

    【讨论】:

      【解决方案2】:

      这就是我想出的,虽然我怀疑每次创建 GetArea() 方法是否“有效”,但这是我知道从原型方法访问局部范围变量的唯一方法:

      var Circle = (function(){
          var Circle = function(radius) {
              this.GetRadius = function(){
                  return radius;
              }
          };
          Circle.prototype.area = function() {
              var rad = this.GetRadius();
              return Math.PI*(rad*rad); 
          };
          return function(radius){
              return new Circle(radius);
          }
      })();
      

      (这将允许访问圆的半径值,但不允许您更改它,这就是我认为您想要这个的原因)

      【讨论】:

      • 与 Šime Vidas 的回答基本相同,但使用工厂设计模式,如果你愿意,可以跳过,我现在只是倾向于将它用于我所有的“类”
      猜你喜欢
      • 2011-09-13
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 2023-04-01
      • 2021-08-18
      • 1970-01-01
      • 2019-05-08
      相关资源
      最近更新 更多