I'm used to classic OOP, like in Java.
What are the best practices for OOP in JavaScript using NodeJS?
Is each class a file with module.export ?
How to create classes?
this.Class = function() { //constructor? var privateField = "" this.publicField = "" var privateMethod = function() {} this.publicMethod = function() {} }
against. (I'm not even sure this is correct)
this.Class = { privateField: "" , privateMethod: function() {} , return { publicField: "" publicMethod: function() {} } }
against.
this.Class = function() {} this.Class.prototype.method = function(){} ...
How does inheritance work?
Are there specific modules for implementing OOP in NodeJS?
I find thousands of different ways to create things that resemble OOP .. but I don’t know what is the most used / practical / clean way.
Bonus question : what is the proposed "OOP style" for use with MongooseJS? (can a MongooseJS document be considered as a class and model used as an instance?)
EDIT
here is an example in JsFiddle , please provide feedback.
//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)