【发布时间】:2012-07-02 07:12:24
【问题描述】:
我正在着手处理一个相当大的 JS 项目,并希望确保我的代码结构清晰有效。我一直在阅读大量关于 JS 中 OOP 的不同方法,但没有找到我真正喜欢的方法。
我很欣赏使用prototype 属性所提供的性能改进,但是当您尝试将真正的私有方法和变量添加到混合中时,它会变得相当混乱。另一方面,我真的很喜欢closure 方法,但我对性能下降感到不舒服。我查看了module 模式,但发现它非常冗长。某处有快乐的媒介吗?
为了说明我正在努力解决的问题,这里有两个非常小的示例类:
点等级:
function Point(x, y) {
this.x = x;
this.y = y;
}
// Get the x coordinate.
Point.prototype.getX = function() {
return this.x;
}
// Get the y coordinate.
Point.prototype.getY = function() {
return this.y;
}
// Get the (x, y) coordinate.
Point.prototype.getXY = function() {
return {x: this.x, y: this.y};
}
// Set the x coordinate.
Point.prototype.setX = function(x) {
this.x = x;
}
// Set the y coordinate.
Point.prototype.setY = function(y) {
this.y = y;
}
// Set the (x, y) coordinate.
Point.prototype.setXY = function(x, y) {
this.x = x;
this.y = y;
}
用户类:
function User(guid) {
var guid = guid;
// Return the user's GUID.
this.getGuid = function() {
return guid;
}
}
在任何给定时间都可能有数千个点对象在使用,所以我觉得prototype 方法是那里的最佳选择。但是,如果我想为坐标设置添加任何验证,只需调用Point.x = <value> 即可绕过它。同样,我可能会在大部分时间调用Point.getXY(),这将为本质上是公共属性的内容构建新对象。我是否应该摆脱 Point 类的 getter 和 setter 的概念,让它创建完全开放的公共对象?这在 OOP 的上下文中似乎是错误的。
对于User 类,我想在内部存储一个GUID,这样它就可以被请求但永远不会被修改。这不能用prototype 方法完成(除非我遗漏了什么),所以我不得不使用某种closure。我预计有数百名用户同时处于活动状态,因此性能不如Point 类那么重要。但是,我真的不想在整个代码库中切换不同类型的 OOP 样式。
所以,作为一个普遍的问题,是否有一种我缺少的 JS 中的 OOP 方法可以让我使用 prototype 属性,同时干净地将选择函数和变量私有化?或者,我看错了方向?我应该以不同的方式处理这个问题吗?
【问题讨论】:
-
如果你真的想要隐私,请使用 Dart 或 GWT。你真的想要吗?
-
@Esailija 我认为隐私在整个代码库中都很重要,所以我想相应地进行计划。然而,我觉得 Dart 和 GWT 作为解决这个问题的方法有点过头了。
-
您只能使用
_前缀之类的约定将方法标记为“内部”,但 javascript 中没有真正的隐私。闭包与它完全不同,只要你提出一个新观点,你就会重新创建每个函数对象。如果有 50 个方法并且您创建了 1000 个点,那就是创建了 49950 个额外的函数对象。最重要的是,闭包拥有数据而不是对象,如果您不经常意识到它可能会产生有趣的结果。请注意,您可以毫无问题地创建“私有方法”,但这并不是一个巨大的胜利。 -
@Esailija 我同意并理解你所说的一切。这个项目在发布时可能会被第三方扩展,所以我正在努力关注适当的封装和隐私。如果您忽略创建大量函数对象的性能影响,那么闭包方法正是我想要的。所以,我希望也许有一些我没有听说过的混合方法可以同时获得性能和隐私。
-
嗯,它适用于流行的库(Google Closure、jQuery 及其插件等)。我敢肯定,如果有人会无视约定和文档并覆盖它,他们可能会在其他语言中使用反射来做到这一点?
标签: javascript oop design-patterns