[javascript] NodeJS의 JavaScript OOP : 어떻게?

Java에서와 같이 고전적인 OOP에 익숙합니다.

NodeJS를 사용하여 JavaScript에서 OOP를 수행하는 모범 사례는 무엇입니까?

각 클래스는 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() {}
    }
}

this.Class = function() {}

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

...

상속은 어떻게 작동합니까?

NodeJS에서 OOP를 구현하기위한 특정 모듈이 있습니까?

OOP와 유사한 것을 만드는 수천 가지 방법을 찾고 있습니다. 그러나 가장 많이 사용되는 / 실용적인 / 깨끗한 방법이 무엇인지 전혀 모릅니다.

보너스 질문 : MongooseJS와 함께 사용하기 위해 제안 된 “OOP 스타일”은 무엇입니까? (MongooseJS 문서를 클래스로 볼 수 있고 모델로 인스턴스로 사용할 수 있습니까?)

편집하다

다음은 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)



답변

이것은 즉시 작동하는 예입니다. 덜 “해키”를 원하면 상속 라이브러리 등을 사용해야합니다.

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;


답변

Node.js 커뮤니티는 JavaScript ECMA-262 사양의 새로운 기능이 적시에 Node.js 개발자에게 제공되도록 보장합니다.

JavaScript 클래스를 살펴볼 수 있습니다 . JS 클래스
에 대한 MDN 링크 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();


답변

inherits표준 util모듈 과 함께 제공 되는 도우미 를 사용하는 것이 좋습니다 . http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor

링크 된 페이지에 사용 방법의 예가 있습니다.


답변

이것은 인터넷에서 객체 지향 JavaScript에 대한 최고의 비디오입니다.

객체 지향 JavaScript에 대한 확실한 가이드

처음부터 끝까지보세요 !!

기본적으로 Javascript는 Java, C ++, C # 및 기타 인기있는 친구의 클래스와는 매우 다른 프로토 타입 기반 언어입니다. 비디오는 여기에있는 어떤 대답보다 핵심 개념을 훨씬 더 잘 설명합니다.

ES6 (2015 년 출시)에서는 Java, C ++, C #, Swift 등과 같이 Javascript “클래스”를 사용할 수있는 “class”키워드를 얻었습니다.

자바 스크립트 클래스 / 하위 클래스를 작성하고 인스턴스화하는 방법을 보여주는 비디오의 스크린 샷 :
여기에 이미지 설명 입력


답변

자바 스크립트 커뮤니티에서 많은 사람들은 프로토 타입 모델이 기본적으로 엄격하고 강력한 OOP를 수행 할 수 없기 때문에 OOP를 사용해서는 안된다고 주장합니다. 그러나 나는 OOP가 언어의 문제가 아니라 아키텍처의 문제라고 생각합니다.

Javascript / Node에서 진정한 강력한 OOP를 사용하려면 풀 스택 오픈 소스 프레임 워크 인 Danf를 살펴볼 수 있습니다. 강력한 OOP 코드 (클래스, 인터페이스, 상속, 종속성 주입 등)에 필요한 모든 기능을 제공합니다. 또한 서버 (노드) 및 클라이언트 (브라우저) 측 모두에서 동일한 클래스를 사용할 수 있습니다. 또한 Npm 덕분에 자신 만의 danf 모듈을 코딩하고 누구와도 공유 할 수 있습니다.


답변

직접 작업하고 있고 Java, C # 또는 C ++에서 찾을 수있는 OOP에 가장 가까운 것을 원한다면 javascript 라이브러리 인 CrxOop을 참조하십시오. CrxOop은 Java 개발자에게 다소 익숙한 구문을 제공합니다.

조심하세요. Java의 OOP는 Javascript에있는 것과 동일하지 않습니다. 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);

코드는 순수한 자바 스크립트이며 트랜스 파일이 아닙니다. 이 예제는 공식 문서의 여러 예제에서 가져 왔습니다.


답변