Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NodeJS中的JavaScript面向对象:如何实现?_Javascript_Node.js_Oop_Inheritance_Mongoose - Fatal编程技术网

NodeJS中的JavaScript面向对象:如何实现?

NodeJS中的JavaScript面向对象:如何实现?,javascript,node.js,oop,inheritance,mongoose,Javascript,Node.js,Oop,Inheritance,Mongoose,我已经习惯了Java中的经典OOP 使用NodeJS在JavaScript中进行OOP的最佳实践是什么 每个类都是一个包含模块的文件。导出 如何创建类 this.Class = function() { //constructor? var privateField = "" this.publicField = "" var privateMethod = function() {} this.publicMethod = function() {}

我已经习惯了Java中的经典OOP

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

每个类都是一个包含
模块的文件。导出

如何创建类

this.Class = function() {
    //constructor?
    var privateField = ""
    this.publicField = ""
    var privateMethod = function() {}
    this.publicMethod = function() {} 
}
vs.(我甚至不确定它是否正确)

vs

继承将如何工作

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

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

奖励问题:建议MongooseJS使用什么“OOP风格”?(MongooseJS文档是否可以看作是一个类和一个用作实例的模型?)

编辑

这里是一个例子,请提供反馈

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

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

在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
模块附带的
inherits
帮助程序:


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

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


如果您想在Javascript/Node中使用真正强大的OOP,可以看看完整的堆栈开源框架。它提供了强OOP代码所需的所有特性(类、接口、继承、依赖项注入等等)。它还允许您在服务器(节点)和客户端(浏览器)上使用相同的类。此外,得益于Npm,您可以编写自己的danf模块并与任何人共享。

作为Node.js社区,确保JavaScript ECMA-262规范中的新功能及时提供给Node.js开发人员

您可以查看JavaScript类。 在介绍ECMAScript 6 JavaScript类时,该方法提供了在JavaScript中建模OOP概念的更简单方法

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

下面是用Node.js编写的类继承的一些框架(使用Node.js版本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();
继承:

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

这是关于internet上面向对象JavaScript的最佳视频:

从头到尾看

基本上,JavaScript是一种与爪哇、C++、C等其他类朋友不同的语言。 这段视频比这里的任何答案都能更好地解释核心概念

用ES6(2015)得到了一个“类”关键字,允许我们使用JavaScript“类”,如java、C++、C语言、SWIFT等。 显示如何编写和实例化Javascript类/子类的视频截图:

< p>如果你自己工作,并且你想在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,没有传输。该示例取自官方文档中的许多示例。

node.JS中没有任何关于OO JS的具体内容。只有oojs。您的问题是如何将Java OOP技术转换为JS,这是不正确的。我认为你最好花同样的时间/精力来学习JS基于原型的模型是如何工作的,以及如何利用它发挥优势。同样,你没有JavaScript类。您可以使用函数创建类行为,但这通常不是一个好主意。@AwakeZoldiek您说它不是“本机功能”是什么意思?@fusio与原型继承一般来说,对象/实例从其他对象/实例继承。因此,不使用类是因为您没有使用抽象定义。因此,继承是通过。而且,不,对象不支持“私有”成员。尽管Node.js中的模块/脚本是作为闭包实现的,但我的意思并不是说闭包可以创建私有成员。他只是建议闭包和封闭的变量都在JavaScript中。但是,对于另一部分:我提到的唯一“实现”是节点模块,它们在闭包中进行评估,其中一些是每个脚本所特有的。使用
Animal.prototype.getAge=function(){}
和简单地添加
this.getAge=function(){}有什么区别
内部
函数动物(){}
?这个小班似乎有点黑。。对于“继承”库,您的意思是像@badsyntax?@fusio建议的那样
inherits
,是的,您可以像
inherits(鼠标、动物)这样做它稍微清理了一点继承设置。不同之处在于,您正在为每个实例化对象创建新的函数标识,而不是共享一个函数。如果您有10个鼠标,您已经创建了10个函数标识(这只是因为鼠标有一个方法,如果它有10个方法,10个鼠标将创建100个函数标识,您的服务器将很快在GC:P上浪费大部分CPU),即使您不会将它们用于任何用途。该语言目前没有足够的表达能力来优化它