这两个小JavaScript类的最佳OOP方法
我正在着手一个相当大的JS项目,并希望确保我的代码结构清晰高效。我一直在阅读JS中大量不同的OOP方法,但还没有找到一种我真正喜欢的方法 我很欣赏使用这两个小JavaScript类的最佳OOP方法,javascript,oop,design-patterns,Javascript,Oop,Design Patterns,我正在着手一个相当大的JS项目,并希望确保我的代码结构清晰高效。我一直在阅读JS中大量不同的OOP方法,但还没有找到一种我真正喜欢的方法 我很欣赏使用prototype属性所带来的性能改进,但是当您试图在混合中添加真正的私有方法和变量时,它会变得相当混乱。另一方面,我非常喜欢闭包方法,但我对性能下降感到不舒服。我查看了模块模式,但发现它非常冗长。有快乐的媒介吗 为了说明我正在努力解决的问题,这里有两个非常小的示例类: 点类: function Point(x, y) { this.x = x
prototype
属性所带来的性能改进,但是当您试图在混合中添加真正的私有方法和变量时,它会变得相当混乱。另一方面,我非常喜欢闭包
方法,但我对性能下降感到不舒服。我查看了模块
模式,但发现它非常冗长。有快乐的媒介吗
为了说明我正在努力解决的问题,这里有两个非常小的示例类:
点类:
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;
}
}
用户类:
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=
即可绕过。类似地,我可能会在大部分时间调用Point.getXY()
,这将为本质上属于公共属性的对象构造新对象。我是否应该摆脱Point
类的getter和setter概念,让它创建完全开放的公共对象?在面向对象的上下文中,这似乎是错误的
对于User
类,我希望在内部存储一个GUID,这样就可以请求它,但永远不会修改它。这不能用prototype
方法来完成(除非我遗漏了什么),所以我不得不使用某种闭包。我预计一次激活的用户数量将达到数百,因此性能不如Point
类重要。然而,我并不想在整个代码库中切换不同类型的OOP风格
因此,作为一个一般性的问题,在JS中是否有一种我缺少的OOP方法,它允许我在干净地私有化选择函数和变量的同时使用prototype
属性?或者,我看错方向了吗?我应该换一种方式来处理这个问题吗?我不知道你的背景,但可能是面向对象的,所以请检查一下我不知道你的背景,但可能是面向对象的,所以请检查一下因为基于原型的对象定向不是真正的对象定向,我认为你可能找错了地方
基于原型的对象是它们的子类的克隆。因此,如果您声明对象有一个属性getXY(),那么它对从该属性克隆的任何对象都是开放的
所以我想真正的问题是,在这个实现中,您认为私有函数能为您带来什么
如果您真的需要私有函数,我建议您处理闭包模式中必须处理的混乱 由于基于原型的面向对象不是真正的面向对象,我认为您可能找错了地方
基于原型的对象是它们的子类的克隆。因此,如果您声明对象有一个属性getXY(),那么它对从该属性克隆的任何对象都是开放的
所以我想真正的问题是,在这个实现中,您认为私有函数能为您带来什么
如果您真的需要私有函数,我建议您处理闭包模式中必须处理的混乱 您可以在开发过程中使用闭包方法,这样您就知道没有人会绕过验证,然后在发布代码时切换到更快的原型方法
var Release = true;
if (Release) {
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;
}
} else {
function Point(x, y) {
var _x = x,
_y = y;
return {
// Get the x coordinate.
getX: function () {
return _x;
},
// Get the y coordinate.
getY: function () {
return _y;
},
// Get the (x, y) coordinate.
getXY: function () {
return {
x: _x,
y: _y
};
},
// Set the x coordinate.
setX: function (x) {
_x = x;
},
// Set the y coordinate.
setY: function (y) {
_y = y;
},
// Set the (x, y) coordinate.
setXY: function (x, y) {
_x = x;
_y = y;
}
}
}
}
您可以在开发过程中使用闭包方法,这样您就知道没有人会绕过验证,然后在发布代码时切换到更快的原型方法
var Release = true;
if (Release) {
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;
}
} else {
function Point(x, y) {
var _x = x,
_y = y;
return {
// Get the x coordinate.
getX: function () {
return _x;
},
// Get the y coordinate.
getY: function () {
return _y;
},
// Get the (x, y) coordinate.
getXY: function () {
return {
x: _x,
y: _y
};
},
// Set the x coordinate.
setX: function (x) {
_x = x;
},
// Set the y coordinate.
setY: function (y) {
_y = y;
},
// Set the (x, y) coordinate.
setXY: function (x, y) {
_x = x;
_y = y;
}
}
}
}
您只能使用文档和约定(如\uuu
前缀)将方法标记为“内部”,但javascript中没有真正的、强制的对象私有成员
闭包是不可接受的——它们将拥有数据,而不是可能具有“有趣”结果的对象,特别是当您希望以这种方式使用闭包扩展“类”时。
另一点是,您将使用O(n)内存来存储所有函数对象,这是不可接受的,如果该库的用户无法控制它,他们可能很容易使用该库,从而导致内存问题
您可以使用下划线前缀约定,如下所示:
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;
}
您只能使用文档和约定(如\uuu
前缀)将方法标记为“内部”,但javascript中没有真正的、强制的对象私有成员
闭包是不可接受的——它们将拥有数据,而不是可能具有“有趣”结果的对象,特别是当您希望以这种方式使用闭包扩展“类”时。
另一点是,您将使用O(n)内存来存储所有函数对象,这是不可接受的,如果该库的用户无法控制它,他们可能很容易使用该库,从而导致内存问题
您可以使用下划线前缀约定,如下所示:
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;
}
如果您真的想要隐私,请使用Dart或GWT。你真的想要它吗?@Esailija我认为隐私在整个代码库中都很重要,所以我想做相应的计划。然而,我觉得Dart和GWT作为这个问题的解决方案有点过头了。你只能使用像\uu
前缀这样的约定来将一个方法标记为“内部”,但javascript中没有真正的隐私。闭包一点也不像它,只要你提出一个新的观点,你就会重新创建每个函数对象。如果有50个方法,你创建了1000个点,那么就创建了49950个额外的函数对象。最重要的是关闭