NodeJS中的JavaScript OOP:怎么样?

我习惯于Java中的传统OOP。

使用NodeJS在JavaScript中执行OOP的最佳做法是什么?

每个类是一个文件与module.export

如何创build类?

 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(){} ... 

inheritance如何工作?

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

我find了千种不同的方法来创build类似于OOP的东西..但我不知道什么是最常用/实用/干净的方式。

奖金问题 :与MongooseJS一起使用的build议“OOP风格”是什么? (可以将MongooseJS文档看作一个Class和一个用作实例的模型?)

编辑

这里是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) 

这是一个开箱即用的例子。 如果你想减less“hacky”,你应该使用inheritance库或类似的东西。

那么在一个文件animal.js中,你会写:

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

如果你想要一个“子类”,那么在mouse.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 (eg 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; 

你也可以考虑“方法借用”而不是垂直inheritance。 你不需要inheritance“类”来在你的类上使用它的方法。 例如:

  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社区,应确保JavaScript ECMA-262规范的新function及时带给Node.js开发人员。

你可以看一下JavaScript类 。 MDN链接到JS类在ECMAScript 6引入了JavaScript类,这个方法提供了更简单的方法来在Javascript中build模OOP概念。

注意 :JS类只能在严格模式下工作

下面是一些类的框架,用Node.js(Used Node.js Version v5.0.0 )编写的inheritance

类声明:

 'use strict'; class Animal{ constructor(name){ this.name = name ; } print(){ console.log('Name is :'+ this.name); } } var a1 = new Animal('Dog'); 

inheritance:

 'use strict'; class Base{ constructor(){ } // methods definitions go here } class Child extends Base{ // methods definitions go here print(){ } } var childObj = new Child(); 

我build议使用标准util模块附带的inherits助手: http : //nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor

有一个如何在链接页面上使用它的例子。

这是关于互联网上面向对象的JavaScript的最佳video:

面向对象JavaScript的权威指南

始终观看!

基本上,Javascript是一种基于Prototype的语言,与Java,C ++,C#和其他stream行的朋友中的类完全不同。 这个video解释了核心概念比这里的任何答案都要好得多。

随着ES6(2015年发布),我们得到了一个“类”关键字,它允许我们像使用Java,C ++,C#,Swift等一样使用Javascript“类”。

显示如何编写和实例化Javascript类/子类的video截图: 在这里输入图像说明

在JavaScript社区中,很多人认为不应该使用OOP,因为原型模型不允许在本地执行严格而强大的OOP。 不过,我不认为面向对象是一个语言问题,而是一个build筑问题。

如果你想在JavaScript / Node中使用一个真正强大的OOP,你可以看看整个开源框架Danf 。 它提供了强大的OOP代码(类,接口,inheritance,dependency injection等)所需的所有function。 它还允许您在服务器(节点)和客户端(浏览器)两端使用相同的类。 此外,你可以编写自己的danf模块,并与任何人分享,这要归功于Npm。