NodeJS 中的 JavaScript OOP:如何?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18188083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript OOP in NodeJS: how?
提问by fusio
I am used to the classical OOP as in Java.
我习惯了 Java 中的经典 OOP。
What are the best practices to do OOP in JavaScript using NodeJS?
使用 NodeJS 在 JavaScript 中执行 OOP 的最佳实践是什么?
Each Class is a file with module.export?
每个类是一个文件module.export?
How to create Classes?
如何创建类?
this.Class = function() {
//constructor?
var privateField = ""
this.publicField = ""
var privateMethod = function() {}
this.publicMethod = function() {}
}
vs. (I am not even sure it is correct)
vs.(我什至不确定它是否正确)
this.Class = {
privateField: ""
, privateMethod: function() {}
, return {
publicField: ""
publicMethod: function() {}
}
}
vs.
对比
this.Class = function() {}
this.Class.prototype.method = function(){}
...
How would inheritance work?
继承将如何运作?
Are there specific modules for implementing OOP in NodeJS?
是否有用于在 NodeJS 中实现 OOP 的特定模块?
I am finding a thousand different ways to create things that resemble OOP.. but I have no clue what is the most used/practical/clean way.
我正在寻找一千种不同的方法来创建类似于 OOP 的东西......但我不知道什么是最常用/最实用/最干净的方法。
Bonus question: what is the suggested "OOP style" to use with MongooseJS? (can a MongooseJS document be seen as a Class and a model used as an instance?)
额外问题:与 MongooseJS 一起使用的建议“OOP 风格”是什么?(可以将 MongooseJS 文档视为一个类和一个用作实例的模型吗?)
EDIT
编辑
here is an example in JsFiddleplease provide feedback.
这是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)
采纳答案by Esailija
This is an example that works out of the box. If you want less "hacky", you should use inheritance library or such.
这是一个开箱即用的示例。如果你想要更少的“hacky”,你应该使用继承库等。
Well in a file animal.js you would write:
那么在文件animal.js中你会写:
var method = Animal.prototype;
function Animal(age) {
this._age = age;
}
method.getAge = function() {
return this._age;
};
module.exports = Animal;
To use it in other file:
要在其他文件中使用它:
var Animal = require("./animal.js");
var john = new Animal(3);
If you want a "sub class" then inside mouse.js:
如果你想要一个“子类”,那么在 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;
Also you can consider "Method borrowing" instead of vertical inheritance. You don't need to inherit from a "class" to use its method on your class. For instance:
您也可以考虑“方法借用”而不是垂直继承。你不需要从“类”继承来在你的类上使用它的方法。例如:
var method = List.prototype;
function List() {
}
method.add = Array.prototype.push;
...
var a = new List();
a.add(3);
console.log(a[0]) //3;
回答by Piyush Sagar
As Node.js community ensure new features from the JavaScript ECMA-262 specification are brought to Node.js developers in a timely manner.
作为 Node.js 社区,确保及时将 JavaScript ECMA-262 规范中的新功能提供给 Node.js 开发人员。
You can take a look at JavaScript classes. MDN link to JS classes In the ECMAScript 6 JavaScript classes are introduced, this method provide easier way to model OOP concepts in Javascript.
您可以查看JavaScript 类。JS 类的 MDN 链接在 ECMAScript 6 中引入了 JavaScript 类,此方法提供了在 Javascript 中对 OOP 概念进行建模的更简单方法。
Note: JS classes will work in only strict mode.
注意:JS 类只能在严格模式下工作。
Below is some skeleton of class,inheritance written in Node.js ( Used Node.js Version v5.0.0)
下面是一些类的骨架,用 Node.js 编写的继承(使用 Node.js 版本v5.0.0)
Class declarations :
类声明:
'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();
回答by badsyntax
I suggest to use the inheritshelper that comes with the standard utilmodule: http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor
我建议使用inherits标准util模块附带的帮助程序:http: //nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor
There is an example of how to use it on the linked page.
在链接页面上有一个如何使用它的示例。
回答by etayluz
This is the best video about Object-Oriented JavaScript on the internet:
这是互联网上关于面向对象的 JavaScript 的最佳视频:
The Definitive Guide to Object-Oriented JavaScript
Watch from beginning to end!!
从头看到尾!!
Basically, Javascript is a Prototype-basedlanguage which is quite different than the classes in Java, C++, C#, and other popular friends. The video explains the core concepts far better than any answer here.
基本上,Javascript 是一种基于原型的语言,它与 Java、C++、C# 和其他流行朋友中的类有很大不同。该视频比此处的任何答案都更好地解释了核心概念。
With ES6 (released 2015) we got a "class" keyword which allows us to use Javascript "classes" like we would with Java, C++, C#, Swift, etc.
在 ES6(2015 年发布)中,我们得到了一个“class”关键字,它允许我们像使用 Java、C++、C#、Swift 等一样使用 Javascript“类”。
Screenshot from the video showing how to write and instantiate a Javascript class/subclass:

回答by Gnucki
In the Javascript community, lots of people argue that OOP should not be used because the prototype model does not allow to do a strict and robust OOP natively. However, I don't think that OOP is a matter of langage but rather a matter of architecture.
在 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.
如果你想在 Javascript/Node 中使用真正强大的 OOP,你可以看看全栈开源框架Danf。它为强大的 OOP 代码(类、接口、继承、依赖注入等)提供了所有需要的特性。它还允许您在服务器(节点)和客户端(浏览器)端使用相同的类。此外,借助 Npm,您可以编写自己的 danf 模块并与任何人共享。
回答by ua692875
If you are working on your own, and you want the closest thing to OOP as you would find in Java or C# or C++, see the javascript library, CrxOop. CrxOop provides syntax somewhat familiar to Java developers.
如果您自己工作,并且想要最接近 OOP 的东西,就像您在 Java、C# 或 C++ 中找到的那样,请参阅 javascript 库 CrxOop。CrxOop 提供了 Java 开发人员有些熟悉的语法。
Just be careful, Java's OOP is not the same as that found in Javascript. To get the same behavior as in Java, use CrxOop's classes, not CrxOop's structures, and make sure all your methods are virtual. An example of the syntax is,
请注意,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);
The code is pure javascript, no transpiling. The example is taken from a number of examples from the official documentation.
代码是纯javascript,没有转译。该示例取自官方文档中的多个示例。

