В этой статье мы разберемся, почему стоит отказаться от использования 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}` }
В приведенном выше коде мы имеем такое же объявление переменной count и экспортируем функцию id (), чтобы она была доступна для других модулей. Так мы скрываем count и открываем id (), как и хотели, только без использования IIFE. В результате мы получаем меньшую вложенность и избавляемся от необходимости определять другую функцию и запускать ее.
Мы можем по-другому создавать алиасы для переменных
Мы могли бы написать такое:
window.$ = function foo() { // ... };(function($) { // ... })(jQuery);
Но теперь нет необходимости использовать IIFE для создания алиасов. Используя модули, мы просто можем импортировать переменную под другим именем, тем самым создавая для нее алиас.
И тогда достаточно написать:
import { $ as jQuery } from "jquery"; const $ = () => {};
Кроме того, не стоит добавлять объекту window новые свойства, так как это загрязняет глобальную область видимости.
Мы можем легко получить глобальный объект
С появлением 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 году для разделения кода мы должны использовать модули и автономные блоки.
Для предотвращения доступа извне к переменным, находящимся внутри модуля, мы можем использовать блочные области видимости.
ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/494868/
Добавить комментарий