[javascript] CommonJs 모듈 시스템에서 “module.exports”와 “exports”의 차이점

이 페이지 ( http://docs.nodejitsu.com/articles/getting-started/what-is-require )에서 “내보내기 오브젝트를 함수 또는 새 오브젝트로 설정하려면 다음을 수행해야합니다. module.exports 객체를 사용하십시오. “

내 질문은 이유입니다.

// right
module.exports = function () {
  console.log("hello world")
}
// wrong
exports = function () {
  console.log("hello world")
}

나는 console.logged 결과 ( result=require(example.js))와 첫 번째 [Function]는 두 번째입니다 {}.

그 이유를 설명해 주시겠습니까? Node.js의 module.exports vs exports 게시물을 읽었습니다 . 도움이되지만 그렇게 설계 한 이유는 설명하지 않습니다. 내보내기 참조가 직접 반환되면 문제가 발생합니까?



답변

moduleexports속성 이있는 일반 JavaScript 객체입니다 . exports로 설정되는 일반 자바 스크립트 변수입니다 module.exports. 파일의 끝에서, Node.js를 기본적 것이다 ‘복귀’ module.exports받는 require기능. Node에서 JS 파일을 보는 간단한 방법은 다음과 같습니다.

var module = { exports: {} };
var exports = module.exports;

// your code

return module.exports;

당신의 속성 설정하면 exports같은 exports.a = 9;설정합니다, module.exports.a객체는 자바 스크립트에서 참조, 같은 개체에 여러 변수를 설정하면, 그들이 그 수단으로 주위에 전달되기 때문에뿐만 아니라 입니다 모두 같은 객체를; 그래서 다음 exportsmodule.exports같은 객체입니다.
사용자가 설정하지만 exports뭔가 새로운, 그것은 더 이상 설정되지 않습니다 module.exports때문에, exports그리고 module.exports더 이상 같은 객체입니다.


답변

Renee의 답변이 잘 설명되어 있습니다. 예를 들어 답변에 추가 :

노드는 파일에 많은 작업을 수행하며 중요한 것 중 하나는 파일 랩핑입니다. 내부 nodejs 소스 코드 “module.exports”가 리턴됩니다. 한 걸음 물러서서 래퍼를 이해할 수 있습니다. 당신이 가지고 있다고 가정

greet.js

var greet = function () {
   console.log('Hello World');
};

module.exports = greet;

위의 코드는 다음과 같이 nodejs 소스 코드 내에 IIFE (즉시 호출 함수 표현식)로 래핑됩니다.

(function (exports, require, module, __filename, __dirname) { //add by node

      var greet = function () {
         console.log('Hello World');
      };

      module.exports = greet;

}).apply();                                                  //add by node

return module.exports;                                      //add by node

위의 함수가 호출되고 (.apply ()) module.exports가 반환됩니다. 현재 module.exports 및 exports는 동일한 참조를 가리 킵니다.

이제 greet.js를 다음과 같이 다시 작성한다고 가정하십시오.

exports = function () {
   console.log('Hello World');
};
console.log(exports);
console.log(module.exports);

출력은

[Function]
{}

그 이유는 다음과 같습니다. module.exports는 빈 객체입니다. 우리는 module.exports에 아무것도 설정하지 않고 새로운 greet.js에서 exports = function () …..을 설정했습니다. 따라서 module.exports가 비어 있습니다.

기술적으로 수출과 module.exports는 동일한 참조를 가리켜 야합니다 (맞습니다 !!). 그러나 function () ….을 내보내기에 할당 할 때 “=”를 사용하여 메모리에 다른 객체를 만듭니다. 따라서 module.exports 및 exports는 다른 결과를 생성합니다. 수출에 관해서는 재정의 할 수 없습니다.

이제 greet.js (Renee 응답 참조)를 다음과 같이 다시 씁니다 (Mutation이라고 함).

exports.a = function() {
    console.log("Hello");
}

console.log(exports);
console.log(module.exports);

출력은

{ a: [Function] }
{ a: [Function] }

보시다시피 module.exports 및 exports는 함수 인 동일한 참조를 가리키고 있습니다. 내보내기에서 속성을 설정하면 JS에서 객체가 참조로 전달되므로 module.exports에서 속성이 설정됩니다.

결론은 혼란을 피하기 위해 항상 module.exports를 사용합니다. 도움이 되었기를 바랍니다. 행복한 코딩 🙂


답변

또한 이해하는 데 도움이 될 수있는 한 가지 사항 :

math.js

this.add = function (a, b) {
    return a + b;
};

client.js

var math = require('./math');
console.log(math.add(2,2); // 4;

이 경우에는 좋습니다.

console.log(this === module.exports); // true
console.log(this === exports); // true
console.log(module.exports === exports); // true

따라서 기본적으로 “this”는 실제로 module.exports와 같습니다.

그러나 구현을 다음과 같이 변경하면

math.js

var add = function (a, b) {
    return a + b;
};

module.exports = {
    add: add
};

이 경우 새 오브젝트가 작성되었으므로 “this”는 더 이상 module.exports와 같지 않습니다.

console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false

그리고 이제 require에 의해 리턴되는 것은 더 이상이 아니라 export.modules에 정의 된 것입니다.

다른 방법은 다음과 같습니다.

math.js

module.exports.add = function (a, b) {
    return a + b;
};

또는:

math.js

exports.add = function (a, b) {
    return a + b;
};


답변

Rene의 답변 exports과 의 관계에 대한 대답은 module.exports분명합니다. 모든 것이 자바 스크립트 참조에 관한 것입니다. 그냥 추가하고 싶습니다 :

우리는 이것을 많은 노드 모듈에서 볼 수 있습니다 :

var app = exports = module.exports = {};

이를 통해 module.exports를 변경하더라도 두 변수가 동일한 객체를 가리 키도록하여 내보내기를 계속 사용할 수 있습니다.


답변

myTest.js

module.exports.get = function () {};

exports.put = function () {};

console.log(module.exports)
// output: { get: [Function], put: [Function] }

exportsmodule.exports같은 동일한 개체에 대한 참조이다. 편의에 따라 두 가지 방법으로 속성을 추가 할 수 있습니다.


답변