基于闭包的对象的效率问题

发布于 2024-10-20 06:19:24 字数 806 浏览 1 评论 0原文

在 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

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

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 编写,因此不希望用户访问内部变量/方法。提前致谢...

One way to define a class in Javascript is with closures and the object literal. As an example, consider a circle:

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

Circle objects can then be instantiated with the internal variables remaining encapsulated:

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

Unfortunately with this method, if I was to create multiple circles the area function would be copied for each instance. This is where the prototyping is usually used:

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

Now the problem is that variables cannot be declared private:

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

Does anyone know how I would get the best of both? Efficiency is an issue so would rather avoid the current formulation of the first method, and I am writing for a public API so don't want users to have access to internal variables/methods. Thanks in advance...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

零度℉ 2024-10-27 06:19:24

怎么样:

function Circle(radius) {
    this.getRadius = function() { return radius; }
}

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

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

  • area,它是从原型继承的,因此使其成为公共方法
  • getRadius code> 被分配给实例对象,从而使其成为实例方法。

不过,radius 值仍然可以通过 getRadius 检索。但是,如果 getRadius 可以确定它是否是从 Circle.prototype 方法中调用的,并且仅返回 radius 值(如果是),那么就会解决它,但我不确定是否可以做到。

How about this:

function Circle(radius) {
    this.getRadius = function() { return radius; }
}

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

Now each instance of the Circle pseudo-class has two methods:

  • area which is inherited from the prototype thus making it a public method
  • getRadius which is assigned to the instance object thus making it an instance method

The radius value is still retrievable via getRadius though. However, if getRadius could determine whether it's called from within a Circle.prototype method and only return the radius value if it is, then that would solve it, but I'm not sure that that can be done.

长梦不多时 2024-10-27 06:19:24

这就是我想到的,尽管我怀疑每次创建 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);
    }
})();

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

This is what I came up with, though whether creating the GetArea() method everytime is "efficient" I doubt, but it's the only way I'm aware of to access the a local scope variable from prototype methods:

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);
    }
})();

(This will allow access to the value of the Radius of the circle, but not allow you to change it, which is why I presume you wanted this)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文