Node.js-생성자로 module.exports 사용


120

Node.js 매뉴얼에 따르면 :

모듈 내보내기의 루트가 함수 (예 : 생성자)가되도록하거나 한 번에 하나의 속성을 빌드하는 대신 하나의 할당으로 전체 객체를 내보내려면 내보내기 대신 module.exports에 할당합니다. .

주어진 예는 다음과 같습니다.

// file: square.js
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

다음과 같이 사용됩니다.

var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());

내 질문 : 예제에서 사각형을 개체로 사용하지 않는 이유는 무엇입니까? 다음이 유효하고 예제를 "객체 지향"으로 만들까요?

var Square = require('./square.js');
var mySquare = new Square(2);
console.log('The area of my square is ' + mySquare.area());

1
귀하의 예는 구문 오류입니다. 이름을 변경 한 후 squareSquarenew square()더 이상 존재하지 않습니다.
Sukima

3
죄송합니다. 오타였습니다. 고쳤다. 내 의도는 대문자로 시작하는 객체 / 함수 이름과 소문자로 시작하는 인스턴스 이름을 표시하는 것이 었습니다.
Naresh

4
나는 많이 생각했다. 그래서 내가했던 방식으로 답을 썼다 . 나는 다른 사람들이 같은 방식으로 모듈을 보는 것이 정말 기쁘다 고 말하고 싶었습니다. 나는 종종 새로운 키워드를 사용하고 단일 생성자 함수를 내보내기 위해 모듈을 구성합니다. 나는 그것이 솔루션의 가독성과 개념화를 더 쉽게 만든다는 것을 알았습니다. 어떤 종류의 구조를 사용하려고하는지 한눈에 알 수 있습니다. 나 같은 생각에 대한 명예)
Sukima

답변:


173

CommonJS 모듈은 내 보낸 속성을 정의하는 두 가지 방법을 허용합니다. 두 경우 모두 개체 / 함수를 반환합니다. 함수는 JavaScript에서 일급 시민이기 때문에 객체처럼 작동 할 수 있습니다 (기술적으로는 객체입니다). new키워드 사용에 대한 귀하의 질문에 간단한 대답이 있습니다. 예. 설명하겠습니다 ...

모듈 내보내기

exports제공된 변수 를 사용하여 속성을 연결할 수 있습니다. 다른 모듈에서 필요한 경우 이러한 할당 속성을 사용할 수 있습니다. 또는 module.exports 속성에 개체를 할당 할 수 있습니다. 두 경우 모두에서 반환되는 require()것은의 값에 대한 참조입니다 module.exports.

모듈 정의 방법에 대한 의사 코드 예제 :

var theModule = {
  exports: {}
};

(function(module, exports, require) {

  // Your module code goes here

})(theModule, theModule.exports, theRequireFunction);

위의 예에서 module.exportsexports같은 목적이다. 멋진 부분은 CommonJS 모듈에서 그 어떤 것도 볼 수 없다는 것입니다. 전체 시스템이 알아서 처리하므로 exports 속성이있는 모듈 객체와 다음을 가리키는 exports 변수가 있다는 것입니다. module.exports가하는 것과 똑같습니다.

생성자에 필요

함수를 직접 첨부 할 수 있기 때문에 module.exports본질적으로 함수를 반환 할 수 있고 다른 함수와 마찬가지로 생성자 로 관리 할 수 ​​있습니다 (JavaScript에서 함수와 생성자 간의 유일한 차이점은 사용하려는 방식이므로 기울임 꼴로 표시됩니다. 다른 점이 없다.)

따라서 다음은 완벽하게 좋은 코드이며 개인적으로 권장합니다.

// My module
function MyObject(bar) {
  this.bar = bar;
}

MyObject.prototype.foo = function foo() {
  console.log(this.bar);
};

module.exports = MyObject;

// In another module:
var MyObjectOrSomeCleverName = require("./my_object.js");
var my_obj_instance = new MyObjectOrSomeCleverName("foobar");
my_obj_instance.foo(); // => "foobar"

비 생성자에게 필요

함수와 같은 비 생성자도 마찬가지입니다.

// My Module
exports.someFunction = function someFunction(msg) {
  console.log(msg);
}

// In another module
var MyModule = require("./my_module.js");
MyModule.someFunction("foobar"); // => "foobar"

2
간단히 require ( './ my-object.js') ( "foobar") 할 수 있습니까? 아니면 다른 사용 사례에 대한 require ( 'module') (params) 구문이 있습니까?
Hampus Ahlgren 2014

1
당신을 막는 것은 없습니다. 그것은 단지 JavaScript 일뿐입니다. 예, 더 짧은 구문을 사용할 수 있습니다.
Sukima

3
모듈 정의 방법에 대한 의사 코드 예제는 Node.js 모듈 시스템에 대한 이해를 완전히 정리했습니다. 감사합니다!
Nitax는

130

제 생각에는 node.js 예제 중 일부는 상당히 인위적입니다.

현실 세계에서 이와 같은 것을 더 많이 볼 것으로 기대할 수 있습니다.

// square.js
function Square(width) {

  if (!(this instanceof Square)) {
    return new Square(width);
  }

  this.width = width;
};

Square.prototype.area = function area() {
  return Math.pow(this.width, 2);
};

module.exports = Square;

용법

var Square = require("./square");

// you can use `new` keyword
var s = new Square(5);
s.area(); // 25

// or you can skip it!
var s2 = Square(10);
s2.area(); // 100

ES6 사람들을 위해

class Square {
  constructor(width) {
    this.width = width;
  }
  area() {
    return Math.pow(this.width, 2);
  }
}

export default Square;

ES6에서 사용

import Square from "./square";
// ...

클래스 사용할 때는 new키워드를 사용하여 instatiate해야합니다. 다른 모든 것은 동일하게 유지됩니다.


3
비정상적으로 간결한 구조!
Christophe Marois 2014

1
따라서 <ES6 예제에서 사용하는 new것과 사용하지 않는 것 사이에 차이가없는 것 같습니다 . 그러나 그것은 당신이 그 수표를 가지고 있기 때문 this instanceof square입니까? 그렇다면 그 메커니즘은 정확히 무엇을하고 있습니까?
arichards

1
다른 사람에게 도움이되는 경우를 대비하여 내가 갖고 검색 한 질문 : 어디에 import있고 export정의되어 있습니까? ECMAScript 6 (ES6)에서 예약 된 키워드입니다. ES6 이전에는 모듈을 관리하기 위해 라이브러리를 사용해야했습니다. Node의 모듈 링은 CommonJS 라이브러리의 모듈을 모델로합니다. 무엇 default인은 export default Square? 이는 해당 파일에서 다른 특정 내보내기가 아닌 '파일'만 가져올 때 가져올 항목을 지정합니다. 존재 하는 한이 페이지가 유용하다는 것을 알았습니다. spring.io/understanding/javascript-modules
explorejs.com/es6/ch_modules.html

1

이 질문은 실제로 require()작동 방식 과 관련이 없습니다 . 기본적으로 module.exports모듈에서 설정 한 내용은 require()호출 에서 반환됩니다 .

이것은 다음과 같습니다.

var square = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

new호출 할 때 키워드 가 필요하지 않습니다 square. 에서 함수 인스턴스 자체를 square반환하는 것이 아니라 마지막에 새 객체를 반환합니다. 따라서이 함수를 직접 호출 할 수 있습니다.

에 대한 더 복잡한 주장은 다음 new을 확인하십시오. JavaScript의 "새"키워드가 유해한 것으로 간주됩니까?


3
새 키워드를 사용하는 데 아무런 문제가 없습니다. 나는 주변의 모든 FUD를 싫어합니다.
Sukima

1
@Sukima 동의합니다. :-D 나는 왜이 경우에 중요하지 않은지 지적하고 new다른 사람들이 그곳에서 전쟁에 참여할 수 있도록 다른 질문과 연결되었습니다 .
Brad

0

예제 코드는 다음과 같습니다.

주로

square(width,function (data)
{
   console.log(data.squareVal);
});

다음을 사용하면 작동 할 수 있습니다.

exports.square = function(width,callback)
{
     var aa = new Object();
     callback(aa.squareVal = width * width);    
}

0

마지막으로 Node는 Javascript에 관한 것입니다. JS는 무언가를 달성하는 여러 가지 방법을 가지고 있으며, "생성자"를 얻는 것과 동일한 것입니다 . 중요한 것은 함수를 반환하는 것 입니다.

예를 들어 웹 브라우저 환경에서 JS를 사용하여 만든 것처럼이 방법은 실제로 새 함수를 만드는 것입니다.

개인적으로 저는 Sukima가이 게시물에서 제안한대로 프로토 타입 접근법을 선호합니다 : Node.js-생성자로 module.exports 사용

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.