JavaScript OOP in NodeJS: how?

我和 Java 一样习惯于经典的 OOP。

在 JavaScript 中使用 NodeJS 进行面向对象编程的最佳实践是什么?

每个类是一个 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() {}
}
}

vs.

this.Class = function() {}


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


...

遗产怎么继承?

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

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

额外的问题 : 在 MongoooseJS 中建议使用什么样的“ OOP 样式”?(一个 MongoooseJS 文档可以看作一个 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)
157528 次浏览

这是一个开箱即用的例子。如果您想要更少的“ hacky”,您应该使用继承库或类似的。

在 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 (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;

您也可以考虑“方法借用”而不是垂直继承。不需要从“类”继承就可以在类上使用它的方法。例如:

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


}


method.add = Array.prototype.push;


...


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

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

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

在 Javascript 社区中,许多人认为不应该使用 OOP,因为原型模型不允许本地执行严格的、健壮的 OOP。然而,我不认为 OOP 是一个语言的问题,而是一个体系结构的问题。

If you want to use a real strong OOP in Javascript/Node, you can have a look at the full-stack open source framework Danf. It provides all needed features for a strong OOP code (classes, interfaces, inheritance, dependency-injection, ...). It also allows you to use the same classes on both the server (node) and client (browser) sides. Moreover, you can code your own danf modules and share them with anybody thanks to Npm.

由于 Node.js 社区确保了来自 JavaScript ECMA-262规范的新特性能够及时地带给 Node.js 开发人员。

你可以看看 JavaScript 类。 < a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Class”> 到 JS 类的 MDN 链接 In the ECMAScript 6 JavaScript classes are introduced, this method provide easier way to model OOP concepts in Javascript.

Note : JS classes will work in only 严格模式.

下面是用 Node.js (二手 Node.js Version V5.0.0)编写的类继承的一些框架

类声明:

'use strict';
class Animal{


constructor(name){
this.name = name ;
}


print(){
console.log('Name is :'+ this.name);
}
}


var a1 = new Animal('Dog');

遗产:

'use strict';
class Base{


constructor(){
}
// methods definitions go here
}


class Child extends Base{
// methods definitions go here
print(){
}
}


var childObj = new Child();

This is the best video about Object-Oriented JavaScript on the internet:

面向对象 JavaScript 通用指南

从头看到尾! !

基本上,Javascript 是一种 基于原型语言,它与 Java、 C + + 、 C # 和其他流行语言中的类完全不同。 视频比这里的任何答案都更好地解释了核心概念。

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

显示如何编写和实例化 Javascript 类/子类的视频截图: enter image description here

如果您正在自己工作,并且您想要在 Java 或 C # 或 C + + 中找到与 OOP 最接近的东西,请参见 javascript 库 CrxOop。CrxOop 提供了 Java 开发人员所熟悉的语法。

小心一点,Java 的 OOP 与 Javascript 中的 OOP 不同。要获得与 Java 中相同的行为,请使用 CrxOop 的类,而不是 CrxOop 的结构,并确保所有方法都是虚方法。这种语法的一个例子是,

crx_registerClass("ExampleClass",
{
"VERBOSE": 1,


"public var publicVar": 5,
"private var privateVar": 7,


"public virtual function publicVirtualFunction": function(x)
{
this.publicVar1 = x;
console.log("publicVirtualFunction");
},


"private virtual function privatePureVirtualFunction": 0,


"protected virtual final function protectedVirtualFinalFunction": function()
{
console.log("protectedVirtualFinalFunction");
}
});


crx_registerClass("ExampleSubClass",
{
VERBOSE: 1,
EXTENDS: "ExampleClass",


"public var publicVar": 2,


"private virtual function privatePureVirtualFunction": function(x)
{
this.PARENT.CONSTRUCT(pA);
console.log("ExampleSubClass::privatePureVirtualFunction");
}
});


var gExampleSubClass = crx_new("ExampleSubClass", 4);


console.log(gExampleSubClass.publicVar);
console.log(gExampleSubClass.CAST("ExampleClass").publicVar);

这段代码是纯 javascript,没有翻译。