【发布时间】:2013-08-13 19:53:51
【问题描述】:
我习惯了 Java 中的经典 OOP。
使用 NodeJS 在 JavaScript 中进行 OOP 的最佳实践是什么?
每个类都是一个带有module.export的文件?
如何创建类?
this.Class = function() {
//constructor?
var privateField = ""
this.publicField = ""
var privateMethod = function() {}
this.publicMethod = function() {}
}
对比(我什至不确定它是否正确)
this.Class = {
privateField: ""
, privateMethod: function() {}
, return {
publicField: ""
publicMethod: function() {}
}
}
对比
this.Class = function() {}
this.Class.prototype.method = function(){}
...
继承如何工作?
是否有在 NodeJS 中实现 OOP 的特定模块?
我正在寻找一千种不同的方法来创建类似于 OOP 的东西。但我不知道最常用/实用/干净的方法是什么。
额外问题:建议使用 MongooseJS 的“OOP 风格”是什么? (MongooseJS 文档是否可以被视为一个类和一个用作实例的模型?)
编辑
这是JsFiddle 中的示例,请提供反馈。
//http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/
function inheritPrototype(childObject, parentObject) {
var copyOfParent = Object.create(parentObject.prototype)
copyOfParent.constructor = childObject
childObject.prototype = copyOfParent
}
//example
function Canvas (id) {
this.id = id
this.shapes = {} //instead of array?
console.log("Canvas constructor called "+id)
}
Canvas.prototype = {
constructor: Canvas
, getId: function() {
return this.id
}
, getShape: function(shapeId) {
return this.shapes[shapeId]
}
, getShapes: function() {
return this.shapes
}
, addShape: function (shape) {
this.shapes[shape.getId()] = shape
}
, removeShape: function (shapeId) {
var shape = this.shapes[shapeId]
if (shape)
delete this.shapes[shapeId]
return shape
}
}
function Shape(id) {
this.id = id
this.size = { width: 0, height: 0 }
console.log("Shape constructor called "+id)
}
Shape.prototype = {
constructor: Shape
, getId: function() {
return this.id
}
, getSize: function() {
return this.size
}
, setSize: function (size) {
this.size = size
}
}
//inheritance
function Square(id, otherSuff) {
Shape.call(this, id) //same as Shape.prototype.constructor.apply( this, arguments ); ?
this.stuff = otherSuff
console.log("Square constructor called "+id)
}
inheritPrototype(Square, Shape)
Square.prototype.getSize = function() { //override
return this.size.width
}
function ComplexShape(id) {
Shape.call(this, id)
this.frame = null
console.log("ComplexShape constructor called "+id)
}
inheritPrototype(ComplexShape, Shape)
ComplexShape.prototype.getFrame = function() {
return this.frame
}
ComplexShape.prototype.setFrame = function(frame) {
this.frame = frame
}
function Frame(id) {
this.id = id
this.length = 0
}
Frame.prototype = {
constructor: Frame
, getId: function() {
return this.id
}
, getLength: function() {
return this.length
}
, setLength: function (length) {
this.length = length
}
}
/////run
var aCanvas = new Canvas("c1")
var anotherCanvas = new Canvas("c2")
console.log("aCanvas: "+ aCanvas.getId())
var aSquare = new Square("s1", {})
aSquare.setSize({ width: 100, height: 100})
console.log("square overridden size: "+aSquare.getSize())
var aComplexShape = new ComplexShape("supercomplex")
var aFrame = new Frame("f1")
aComplexShape.setFrame(aFrame)
console.log(aComplexShape.getFrame())
aCanvas.addShape(aSquare)
aCanvas.addShape(aComplexShape)
console.log("Shapes in aCanvas: "+Object.keys(aCanvas.getShapes()).length)
anotherCanvas.addShape(aCanvas.removeShape("supercomplex"))
console.log("Shapes in aCanvas: "+Object.keys(aCanvas.getShapes()).length)
console.log("Shapes in anotherCanvas: "+Object.keys(anotherCanvas.getShapes()).length)
console.log(aSquare instanceof Shape)
console.log(aComplexShape instanceof Shape)
【问题讨论】:
-
node.js 中没有关于 OO JS 的真正具体。只有OO JS。您的问题是关于 translating Java OOP 技术到 JS,这只是 不正确。我认为你最好花同样的时间/精力来学习 JS 的基于原型的模型是如何工作的,以及如何利用它来发挥你的优势
-
另外,JavaScript 中没有类。您可以使用函数创建类似类的行为,但这通常不是一个好主意。
-
@AwakeZoldiek 你说它不是“原生功能”是什么意思?
-
@fusio 通常使用原型继承,对象/实例继承自其他对象/实例。因此,不使用类是因为您没有使用抽象定义。因此,继承是通过
prototypechain 完成的。而且,不,对象不支持“private”成员。只有 closures 可以提供,尽管 Node.js 中的模块/脚本是作为闭包实现的。 -
@Esailija 我实际上并不是要建议闭包可以创建私有成员。只是建议闭包和封闭变量在 JavaScript 中是as close as you can get。但是,对于另一部分:我提到的唯一“实现”考虑了 Node 模块,这些模块在闭包中进行评估,其中一些 globals 被定义为每个脚本唯一的。
标签: javascript node.js oop inheritance mongoose