Познакомьтесь с iffy в JS (или освежите память за 3 минуты :))
Термин Выражение немедленно вызываемой функции звучит очень элитарно и продвинуто, но на самом деле он очень прост.
Я подготовил для вас несколько примеров, а также распространенные ловушки, с которыми вы можете столкнуться во время собеседования.
Как правильно это сделать
IIFE — это способ немедленного выполнения функций, как только они созданы. Мы можем сделать это, заключив всю функцию в скобки, за которой следует ()
.
Это хороший способ защитить область действия вашей функции и определенные в ней переменные. IIFE создает свою собственную область видимости.
Примеры
Базовый синтаксис (обратите внимание на круглые скобки)
(function() { /* your work here */ const scopedVariable = "I am available only in this block";
console.log(`You will see me in the console. ${scopedVariable}`); })()
// or with arrow function(() => { /* your work here */
const scopedVariable = "I am available only in this block";
console.log(`You will see me in the console. ${scopedVariable}`);
})()
Мы можем немного изменить синтаксис. ()
теперь находится внутри скобок выражения.
Работает так же (просто сохраняйте кодовую базу согласованной).
(function() {
/* still works */
}())
(() => {
/* still works */
}())
Мы также можем дать имя нашей функции — и имя функции namedStillScoped
не «утекает» в глобальное пространство имен.
(function namedStillScoped() { console.log("puma"); })();
Я также видел это в дикой природе:
;(function() {
/* */
})()
На самом деле это хитрый трюк старой школы, поскольку он предотвращает проблемы при слепом объединении двух вещей.
Поскольку JavaScript не требует точек с запятой, мы (или упаковщик) можем объединить слишком много случайностей. Что-то вроде этого вылетит:
const willCrash = 'Hi there!'(function () {
// note the lack of semicolon after 'Hi There!'
})();
Поскольку инструменты linting, веб-пакет и т. д., это редко бывает.
Но все же полезно об этом знать.
IIFE может принимать параметры и возвращать значение
Здесь мы используем функцию параметров по умолчанию ES6, а также создаем объект с коротким синтаксисом.
const person = (function (name = "puma", id = 1) { return { id, name, }; })(); console.log(person); // { id: 1, name: 'puma' }
IIFE для создания служебной переменной
Мы можем создать объект с помощью методов.
<script src="https://cdnurl.com/somelibrary.js"></script> <script> const myUtility = (function () { function createMyUtility() { // logic here } function anotherMyUtilityMethod() { // logic here } return { createMyUtility, anotherMyUtilityMethod } })();
</script>
Мы можем использовать его так myUtility.createMyUtility()
.
Это особенно полезно, когда мы создаем некоторые плагины или пакеты, и мы хотим, чтобы имена были ограничены.
Использование асинхронного ожидания
Вы также можете сделать что-то подобное (пример взят из среды Node.js).
Мы не можем использовать await
вне async
, и тогда IIFE
может нам помочь.
Пример, конечно, упрощен, просто чтобы дать вам подсказку, что это вариант.
(async () => { try { await doSomething(); } catch (e) { console.error(e.stack); process.exit(1); }})();
Пара слов о let и const
ES6 представил нам let
и const
.
Оба они используют область действия блока.
Имея это в виду, теперь мы можем ограничить пространство имен переменных фигурными скобками, не заключая их в функцию IIFE.
Во многих случаях этого недостаточно, и именно поэтому мы должны знать и понимать IIFE.
Сценарий интервью
Вопрос «расскажите мне о IIFE» до сих пор является очень распространенным вопросом на собеседованиях.
Часто появляется дополнительный вопрос, например, простой фрагмент:
function foo(){ // will I run? }();
Мы уже знаем, что синтаксис неверен и что он должен быть одним из следующих:
(function foo() { // I will run because of the wrapping parenthesis
})() // or this(function foo() { // I will run too
}())
Другой вопрос, который вы можете получить, — «почему он возвращает значение undefined»:
const foo = void (function bar() { return 'foo'; })(); console.log(foo); // undefined
Теперь это ловушка, потому что IIFE будет работать. Тогда почему он возвращает undefined
?
Это сводится к ключевому слову void
, которое указывает, что функция ничего не возвращает. Если мы удалим ключевое слово void
, IIFE будет работать правильно.
TL;DR
IIFE в JavaScript:
- вызываются сразу после создания
- отличный способ защитить область видимости (IIFE создает собственную область видимости)
- синтаксис IIFE (помните об скобках и
()
в конце для вызова функции
(function() {
/* */
})()
(() => {
/* */
})()
Резюме
Как мы видим, IIFE в JavaScript на самом деле простая, но мощная функция.
Его определенно стоит иметь в заднем кармане.