لماذا حان الوقت للتوقف عن استخدام JavaScript IIFE

إن وظيفة التعبير عن الوظائف التي يتم استدعاؤها على الفور (IIFE) في JavaScript هي بنية تسمح لك باستدعاء دالة مباشرة بعد تعريفها.

صورة

في هذه المقالة ، سوف نفهم لماذا يجدر التخلي عن استخدام IIFE ، على الرغم من مزاياها السابقة.

يمكن أن نعلن المتغيرات داخل الكتل المستقلة


منذ ظهور معيار ES6 ، يمكننا تعريف المتغيرات والثوابت داخل كتلة باستخدام let و const. إلى جانب هذا المعيار ، أصبح من الممكن أيضًا تخصيص المتغيرات والثوابت في كتل مستقلة ، لا يمكن الوصول إليها من الخارج.

على سبيل المثال:

{
 let x = 1;
}

عندها لن تكون X قابلة للوصول خارجيًا. من الواضح أن هذا أفضل من:

(()=>{
 let x = 1;
})();

الآن بعد أن تم دعم ES6 من قبل جميع المتصفحات الحديثة تقريبًا ، يجب أن نتوقف عن استخدام IIFE لفصل المتغيرات عن العالم الخارجي. طريقة أخرى لعزل المتغيرات هي الوحدات التي ليس لديها الآن مشاكل في دعمها أيضًا. حتى يتم تصديرها ، لن تكون متاحة للوحدات الأخرى.

يمكننا التخلص من جميع عمليات الإغلاق تقريبًا


الإغلاق هو آلية تتذكر من خلالها الدالة المتغيرات الخارجية ويمكنها الوصول إليها. إذا أنشأنا وظيفة أخرى وأعادناها داخل الوظيفة ، فستكون الوظيفة المرتجعة قادرة على الوصول إلى المتغيرات الخارجية الداخلية للوظيفة الخارجية.

على سبيل المثال ، هنا يمكننا الحصول على بعض الآثار الجانبية:

const id = (() => {
 let count = 0;
 return () => {
   ++count;
   return `id_${count}`;
 };
})();

مرة أخرى ، الآن لا معنى لتسييج هذه الحديقة بأكملها ، نظرًا لأن لدينا كتل ووحدات مستقلة لعزل البيانات. يمكننا فقط وضع كل هذا في وحدتنا الخاصة ، فلن نحتاج للقلق بشأن الوصول إلى البيانات.

تسبب عمليات الإغلاق آثارًا جانبية ، وهي ليست جيدة جدًا ، حيث إن أفضل الممارسات والحس السليم يرشدنا إلى تجنبها كلما أمكن ذلك. إنها تجعل من الصعب اختبار الوظائف غير النظيفة في هذه الحالة.

بالإضافة إلى ذلك ، لا يجب أن تنتج وظائف متداخلة عندما يمكن تجنب ذلك: تصبح التعليمات البرمجية أكثر إرباكًا من دونها.
أفضل بديل هو استبدالها بوحدات نمطية:

let count = 0;
export const id = () => {
 ++this.count;
 return `id_${count}`
}

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

يمكننا إنشاء أسماء مستعارة للمتغيرات بشكل مختلف.


يمكننا كتابة هذا:

window.$ = function foo() {
 // ...
};(function($) {
 // ...
})(jQuery);

ولكن الآن ليست هناك حاجة لاستخدام IIFE لإنشاء الأسماء المستعارة. باستخدام الوحدات النمطية ، يمكننا ببساطة استيراد متغير باسم مختلف ، وبالتالي إنشاء اسم مستعار له.

ثم اكتب فقط:

import { $ as jQuery } from "jquery";
const $ = () => {};

بالإضافة إلى ذلك ، لا يجب عليك إضافة خصائص جديدة إلى كائن النافذة ، لأن هذا يلوث النطاق العام.

يمكننا بسهولة الحصول على كائن عالمي.


مع ظهور globalThis ، لا داعي للقلق بشأن اسم الكائن العام في بيئات مختلفة لأنه يصبح المعيار.

يمكننا استخدام IIFE لالتقاط كائن عالمي:

(function(global) {
 // ...
})(this);

ولكن الآن هذا ليس ضروريا. نعم ، وقبل ذلك كان من الممكن الاستغناء عن هذا ببساطة عن طريق كتابة السطر التالي:

const globalObj = self || window || global;

لتوضيح ذلك ، يمكنك كتابة هذا:

const getGlobal = () => {
 if (typeof self !== 'undefined') { return self; }
 if (typeof window !== 'undefined') { return window; }
 if (typeof global !== 'undefined') { return global; }
 throw new Error('unable to locate global object');
};

وبعد ذلك لا يمكنك إضافة استدعاء وظيفة إضافية وتعشيش يظهر عند استخدام IIFE.

يمكننا أن نجعل التصغير أسهل


مع وحدات JavaScript ، لم نعد بحاجة لفصل باقي الكود من IIFE من أجل تقليل ملفاتنا بشكل صحيح.

يمكن أن تعمل Webpack و Browserify و Parcel و Rollup وما إلى ذلك مع الوحدات بشكل صحيح ، لذلك يجب علينا استخدامها لإنشاء رمز أنظف.

استنتاج


حان الوقت للتوقف عن استخدام IIFE في الكود الخاص بنا. هذا يضيف وظائف إضافية وتعشيش فائض.

بالإضافة إلى ذلك ، الآن هذه مفارقة تاريخية: تم استخدام IIFE حتى قبل ظهور واستخدام الوحدات على نطاق واسع في JavaScript. في عام 2020 ، يجب علينا استخدام الوحدات والكتل المستقلة لفصل الرمز.

لمنع الوصول الخارجي إلى المتغيرات داخل الوحدة النمطية ، يمكننا استخدام نطاقات الكتلة.


All Articles