Op deze pagina (http://docs.nodejitsu.com/articles/getting-started/what-is-require), staat er dat “Als u het exportobject wilt instellen op een functie of een nieuw object , moet u het object module.exports gebruiken.”
Mijn vraag is waarom.
// right
module.exports = function () {
console.log("hello world")
}
// wrong
exports = function () {
console.log("hello world")
}
Ik heb het resultaat gelogd (result=require(example.js)
) en de eerste is [Function]
de tweede is {}
.
Kunt u alstublieft de reden erachter uitleggen? Ik lees het bericht hier: module.exports vs exports in Node.js . Het is nuttig, maar verklaart niet waarom het op die manier is ontworpen. Zal er een probleem zijn als de referentie van export rechtstreeks wordt geretourneerd?
Antwoord 1, autoriteit 100%
module
is een eenvoudig JavaScript-object met een eigenschap exports
. exports
is een gewone JavaScript-variabele die toevallig is ingesteld op module.exports
.
Aan het einde van je bestand zal node.js in principe module.exports
‘retourneren’ naar de functie require
. Een vereenvoudigde manier om een JS-bestand in Node te bekijken zou deze kunnen zijn:
var module = { exports: {} };
var exports = module.exports;
// your code
return module.exports;
Als je een eigenschap instelt op exports
, zoals exports.a = 9;
, zal dat ook module.exports.a
instellen omdat objecten als referenties in JavaScript worden doorgegeven, wat betekent dat als je meerdere variabelen instelt op hetzelfde object, ze allemaal hetzelfde object zijn; dus dan zijn exports
en module.exports
hetzelfde object.
Maar als je exports
instelt op iets nieuws, wordt het niet langer ingesteld op module.exports
, dus exports
en module.exports
zijn niet langer hetzelfde object.
Antwoord 2, autoriteit 10%
Renee’s antwoord is goed uitgelegd. Aanvulling op het antwoord met een voorbeeld:
Node doet veel dingen met je bestand en een van de belangrijkste is je bestand WRAPPEN. Binnen nodejs wordt de broncode “module.exports” geretourneerd. Laten we een stap terug doen en de verpakking begrijpen. Stel dat u
greet.js
var greet = function () {
console.log('Hello World');
};
module.exports = greet;
de bovenstaande code is als volgt verpakt als IIFE (Immediately Invoked Function Expression) in de broncode van nodejs:
(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
en de bovenstaande functie wordt aangeroepen (.apply()) en module.exports geretourneerd.
Op dit moment wijzen module.exports en exports naar dezelfde referentie.
Stel je nu voor dat je herschrijft
groet.js als
exports = function () {
console.log('Hello World');
};
console.log(exports);
console.log(module.exports);
de uitvoer zal zijn
[Function]
{}
de reden is: module.exports is een leeg object. We hebben niets ingesteld op module.exports, maar we hebben export = function()…..in new greet.js ingesteld. Dus module.exports is leeg.
Technisch gezien zouden exports en module.exports naar dezelfde referentie moeten verwijzen (dat klopt!!). Maar we gebruiken “=” bij het toewijzen van functie()… aan exports, waardoor een ander object in het geheugen wordt gemaakt. Dus module.exports en exports leveren verschillende resultaten op. Als het op export aankomt, kunnen we het niet negeren.
Stel je nu voor dat je herschrijft (dit heet Mutatie)
greet.js (verwijzend naar het antwoord van Renee) als
exports.a = function() {
console.log("Hello");
}
console.log(exports);
console.log(module.exports);
de uitvoer zal zijn
{ a: [Function] }
{ a: [Function] }
Zoals je kunt zien, verwijzen module.exports en exports naar dezelfde referentie die een functie is. Als u een eigenschap op exports instelt, wordt deze ingesteld op module.exports omdat in JS objecten worden doorgegeven door verwijzing.
De conclusie is om altijd module.exports te gebruiken om verwarring te voorkomen.
Ik hoop dat dit helpt. Veel plezier met coderen 🙂
Antwoord 3, autoriteit 4%
Ook een ding dat kan helpen om te begrijpen:
math.js
this.add = function (a, b) {
return a + b;
};
client.js
var math = require('./math');
console.log(math.add(2,2); // 4;
Geweldig, in dit geval:
console.log(this === module.exports); // true
console.log(this === exports); // true
console.log(module.exports === exports); // true
Dus standaard is “dit” eigenlijk gelijk aan module.exports.
Als u uw implementatie echter wijzigt in:
math.js
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
In dit geval werkt het prima, maar “this” is niet meer gelijk aan module.exports, omdat er een nieuw object is gemaakt.
console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false
En nu, wat wordt geretourneerd door de eis, is wat is gedefinieerd in module.exports, niet dit of exports, meer.
Een andere manier om dit te doen is:
math.js
module.exports.add = function (a, b) {
return a + b;
};
Of:
math.js
exports.add = function (a, b) {
return a + b;
};
Antwoord 4, autoriteit 2%
Rene’s antwoord over de relatie tussen exports
en module.exports
is vrij duidelijk, het draait allemaal om javascript-referenties. Ik wil alleen dat toevoegen:
We zien dit in veel knooppuntmodules:
var app = exports = module.exports = {};
Dit zorgt ervoor dat zelfs als we module.exports hebben gewijzigd, we exports nog steeds kunnen gebruiken door die twee variabelen naar hetzelfde object te laten verwijzen.
Antwoord 5
mijnTest.js
module.exports.get = function () {};
exports.put = function () {};
console.log(module.exports)
// output: { get: [Function], put: [Function] }
exports
en module.exports
zijn hetzelfde en verwijzen naar hetzelfde object. U kunt op beide manieren eigendommen toevoegen, afhankelijk van uw gemak.
Antwoord 6
Omdat alle hierboven geposte antwoorden goed zijn uitgelegd, wil ik iets toevoegen waarmee ik vandaag werd geconfronteerd.
Als je iets exporteert met behulp van exports, dan moet je het met variabele gebruiken. Vind ik leuk,
Bestand1.js
exports.a = 5;
In een ander bestand
File2.js
const A = require("./File1.js");
console.log(A.a);
en het gebruik van module.exports
Bestand1.js
module.exports.a = 5;
In File2.js
const A = require("./File1.js");
console.log(A.a);
en standaard module.exports
Bestand1.js
module.exports = 5;
in File2.js
const A = require("./File2.js");
console.log(A);
Antwoord 7
node doet zoiets als dit:
module.exports = exports = {}
module.exports en exports verwijzen naar hetzelfde object.
Dit is alleen voor het gemak gedaan.
dus in plaats van zoiets te schrijven
module.exports.PI = 3.14
we kunnen schrijven
exports.PI = 3.14
het is dus oké om een eigenschap toe te voegen aan exports, maar het toewijzen aan een ander object is niet oké
exports.add = function(){
.
.
}
^ dit is OK en hetzelfde als module.exports.add = function(){…}
exports = function(){
.
.
}
^ dit is niet ok en een leeg object wordt geretourneerd omdat module.exports nog steeds verwijst naar {} en exports verwijst naar een ander object.