我已经习惯了Java中的classic OOP.

使用NodeJS在JavaScript中进行OOP的最佳实践是什么?

每个类是一个包含module.export个的文件?

如何创建类?

this.Class = function() {
    //constructor?
    var privateField = ""
    this.publicField = ""
    var privateMethod = function() {}
    this.publicMethod = function() {} 
}

vs(我甚至不确定它是否正确)

this.Class = {
    privateField: ""
    , privateMethod: function() {}

    , return {
        publicField: ""
        publicMethod: function() {}
    }
}

与.

this.Class = function() {}

this.Class.prototype.method = function(){}

...

遗产如何运作?

在NodeJS中是否有实现OOP的特定模块?

我正在寻找一千种不同的方法来创造类似OOP的东西..但我不知道什么是最常用/实用/干净的方式.

Bonus question:MongooseJS建议使用什么"OOP风格"?(MongooseJS文档能否被视为一个类和一个用作实例的模型?)

EDIT

下面是一个例子,请提供反馈.

//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)

推荐答案

这是一个开箱即用的例子.如果你想减少"黑客",你应该使用继承库或类似的东西.

好吧,在一个动物的档案里.你会写:

var method = Animal.prototype;

function Animal(age) {
    this._age = age;
}

method.getAge = function() {
    return this._age;
};

module.exports = Animal;

要在其他文件中使用它:

var Animal = require("./animal.js");

var john = new Animal(3);

如果你想要一个"子类",那么里面的鼠标.js:

var _super = require("./animal.js").prototype,
    method = Mouse.prototype = Object.create( _super );

method.constructor = Mouse;

function Mouse() {
    _super.constructor.apply( this, arguments );
}
//Pointless override to show super calls
//note that for performance (e.g. inlining the below is impossible)
//you should do
//method.$getAge = _super.getAge;
//and then use this.$getAge() instead of super()
method.getAge = function() {
    return _super.getAge.call(this);
};

module.exports = Mouse;

你也可以考虑"方法borrow "而不是纵向继承.在类上使用其方法不需要从"类"继承.例如:

 var method = List.prototype;
 function List() {

 }

 method.add = Array.prototype.push;

 ...

 var a = new List();
 a.add(3);
 console.log(a[0]) //3;

Node.js相关问答推荐

postgresql层与应用层的序列化

如何在mongodb集合中设置数据限制?

设置默认 node 版本

如何从shell脚本中计算ecmascript模块?

MongoDB的方面查询的Postgres类似功能

一个大型的单个 Redis 实例可以处理所有事情,还是多个 Redis 实例?

编写动态创建的 YAML - 为生态系统创建 Docker compose 文件(使用 js-yaml)

Next.js 在我的电脑上没有构建错误,但它们在使用 Vercel 部署时发生

如何使用 NodeJS 加密模块将 ECDH 密钥转换为 PEM 格式

在 nodejs 中使用 multer 上传文件返回未定义的 req.file 和空的 req.body

如何为一个网站实现这 2 个网址.即 www.administrator.sitename.com 和 www.sitename.com?

Node.js + Express 上的多个视图路径

异步函数 - 等待不等待promise

TypeError:winston.Logger 不是带有winston 和morgan 的构造函数

使用 Webpack 和 font-face 加载字体

使用 NodeJS 将新对象附加到 DynamoDB 中的 JSON 数组

JavaScript 异步编程:promise 与生成器

为什么 Node.js 被命名为 Node.js?

如何调试 Gulp 任务?

deno vs ts-node:有什么区别