إن وظيفة التعبير عن الوظائف التي يتم استدعاؤها على الفور (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 ، يجب علينا استخدام الوحدات والكتل المستقلة لفصل الرمز.لمنع الوصول الخارجي إلى المتغيرات داخل الوحدة النمطية ، يمكننا استخدام نطاقات الكتلة.