이 페이지 ( 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 게시물을 읽었습니다 . 도움이되지만 그렇게 설계 한 이유는 설명하지 않습니다. 내보내기 참조가 직접 반환되면 문제가 발생합니까?
답변
module
exports
속성 이있는 일반 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
객체는 자바 스크립트에서 참조, 같은 개체에 여러 변수를 설정하면, 그들이 그 수단으로 주위에 전달되기 때문에뿐만 아니라 입니다 모두 같은 객체를; 그래서 다음 exports
과 module.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] }
exports
과 module.exports
같은 동일한 개체에 대한 참조이다. 편의에 따라 두 가지 방법으로 속성을 추가 할 수 있습니다.