English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

شرح الفرق بين exports و module.exports في nodejs

استخدام require لتحميل الكود، بينما تستخدم exports و module.exports لتحميل الكود. لكن العديد من المبتدئين قد يشعرون بالحيرة حول الفرق بين exports و module.exports، لنفهم أفضل علاقة بينهما، دعنا نتعقيد قليلاً في أساسيات js. مثال:

app.js

var a = {name: 'nswbmw 1'};
var b = a;
console.log(a);
console.log(b);
b.name = 'nswbmw 2';
console.log(a);
console.log(b);
var b = {name: 'nswbmw 3'};
console.log(a);
console.log(b);

نتيجة تشغيل app.js هي:

{ name: 'nswbmw 1' }
{ name: 'nswbmw 1' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 3' }

لنوضح ذلك:a هو جسم، b هو مرجع إلى a، أي أن a و b يشيران إلى نفس الجسم، أي أن a و b يشيران إلى نفس عنوان الذاكرة، لذا الناتجان الأوليان متطابقان. عند تعديل b، أي عندما يُحدث تغيير في المحتوى الذي يشير إليه a و b بنفس عنوان الذاكرة، فإن a سيفسد أيضًا، لذا الناتجان الثالث والرابع متطابقان. عند تغطية b بشكل كامل، يصبح b يشير إلى عنوان ذاكرة جديد (لم يتم تعديل الجسم الأصلي)، يظل a يشير إلى الجسم الأصلي، أي أن a و b لا يشيران إلى نفس عنوان الذاكرة، مما يعني أن a و b لم يعد لهما أي علاقة، لذا الناتجان الأخيران مختلفان.

بعد فهم الأمثلة السابقة، دعنا ننتقل إلى الموضوع الرئيسي.

لنفهم الفرق بين exports و module.exports، يكفي أن نعرف ثلاثة أمور:

  • exports هي مرجع إلى module.exports
  • القيمة الافتراضية لـ module.exports هي جسم فارغ {}، لذا القيمة الافتراضية لـ exports هي أيضًا {}
  • يعود(require()) إلى module.exports وليس إلى exports

لذا، نحن نستخدم

var name = 'nswbmw';
exports.name = name;
exports.sayName = function() {
 console.log(name);
{}

تم تعيين(exports) في الواقع لتضيف اثنين من الخصائص إلى المع�체 الفارغ(module.exports)، مما يعني أن الكود المذكور أعلاه يساوي:

var name = 'nswbmw';
module.exports.name = name;
module.exports.sayName = function() {
 console.log(name);
{}

نستخدم عادة exports و module.exports بهذه الطريقة

مثال بسيط لحساب مساحة دائرة:

استخدام exports

app.js

var circle = require('./circle');
console.log(circle.area(4));

circle.js

exports.area = function(r) {
 return r * r * Math.PI;
{}

استخدام module.exports

app.js

var area = require('./area');
console.log(area(4));

area.js

module.exports = function(r) {
 return r * r * Math.PI;
{}

تكون نتيجة الأثنتين متشابهة. قد تسأل لماذا لا نكتب بهذه الطريقة؟

app.js

var area = require('./area');
console.log(area(4));

area.js

exports = function(r) {
 return r * r * Math.PI;
{}

تسبب في الخطأ عند تشغيل الأمثلة السابقة. هذا لأننا، في الأمثلة السابقة، قمنا بتعديل(exports) عن طريق إضافة خصائص، مما أدى إلى تعديل الذاكرة التي يوجه إليها(exports)، ولكن

exports = function(r) {
 return r * r * Math.PI;
{}

في الواقع، تم تغيير(exports) للوصول إلى ذاكرة جديدة (محتواها هو دالة لحساب مساحة دائرة)، مما يعني أن(exports) و(module.exports) لا يوجهان إلى نفس الذاكرة، مما يعني أن(exports) و(module.exports) ليس لهما أي علاقة في هذه اللحظة، مما يعني أن الذاكرة التي يوجه إليها(module.exports) لم يتم تغييرها بعد، وتبقى كمع�체 فارغ{}، مما يعني أن(area.js) قد صدر بمع�체 فارغ، لذا عندما نحاول استدعاء(area(4)) في(app.js) سنحصل على خطأ TypeError: object is not a function.

بنابراین، در یک جمله خلاصه می‌کنیم: زمانی که می‌خواهیم یک مودول یک شیء را صادر کند، از exports و module.exports می‌توان استفاده کرد (اما exports نیز نمی‌تواند به یک شیء جدید پوشش داده شود)، و زمانی که می‌خواهیم یک رابط غیر شیء را صادر کنیم، باید فقط module.exports را پوشش دهیم.

همچنین این روش را زیاد می‌بینیم که:

exports = module.exports = somethings;

کد بالا معادل است با

module.exports = somethings;
exports = module.exports;

دلیل این مسئله نیز ساده است، module.exports = somethings به معنای پوشش module.exports است، در این حالت ارتباط module.exports و exports قطع شده است، module.exports به یک بلوک حافظه جدید اشاره دارد، در حالی که exports هنوز به بلوک حافظه قبلی اشاره دارد، برای اینکه module.exports و exports هنوز به یک بلوک حافظه یا یک 'اشیاء' مشابه اشاره کنند، پس ما از exports = module.exports استفاده می‌کنیم.

این تمام محتوای این مقاله است، امیدواریم محتوای این مقاله به شما در یادگیری یا کار شما کمک کند، همچنین امیدواریم که بیش از پیش از آموزش‌های فریاد حمایت کنید!

اظهارنامه: محتوای این مقاله از اینترنت است، حق مالکیت آن به صاحب‌کار آن تعلق دارد، محتوا به طور خودجوش توسط کاربران اینترنت ارائه شده و بارگذاری شده است، این وب‌سایت مالکیت آن را ندارد، از آن برای ویرایش دستی استفاده نشده است و هیچ مسئولیتی در این زمینه ندارد. اگر محتوایی که مشمول حق انحصاری است را شناسایی کردید، خوشحال می‌شویم که یک ایمیل به آدرس notice#oldtoolbag.com (هنگام ارسال ایمیل، لطفاً # را به @ تبدیل کنید) ارسال کنید تا گزارش دهید و مدارک مرتبط را ارائه دهید، اگر پس از بررسی واقعاً مشمول حق انحصاری بود، این وب‌سایت محتوای مشمول حق انحصاری را بلافاصله حذف خواهد کرد.

أنت قد تحب