Рубрики
Без рубрики

JavaScript сразу вызывала функциональные выражения

Немедленно вызываемые выражения функций (IFFE) – это обычный шаблон JavaScript, который мгновенно выполняет функцию по определению, а затем вызывает его после этого.

Автор оригинала: Allan Mogusu.

Вступление

Определение и вызывающие функции являются ключевыми методами для освоения JavaScript и большинства других языков программирования. Обычно функция определена до того, как она вызывается в вашем коде.

Немедленно вызванные функциональные выражения (IIFIFE), произносится «IFFY», являются обычным шаблоном JavaScript, которая мгновенно выполняет функцию после определения его. Разработчики в основном используют этот шаблон для обеспечения доступности переменных только в рамках определенной функции.

В этой статье вы сначала узнаете о функциональных выражениях. После того, как мы пойдем дальше в IFES – как их писать и когда их использовать. Наконец, мы обсудим, как Пусть Ключевое слово введено в ECMAScript 6, обеспечивает очистительную альтернативу для некоторых случаев использования IIFE.

Что такое функциональные выражения?

В JavaScript вы можете определить функцию 2 разных способов:

  1. Декларация
  2. Выражение

Функциональные объявления начать с Функция Ключевое слово, а затем имя функции и любые аргументы, которые он может занять. Например, мы можем создать logname Функция, используя такую декларацию:

function logName(userName) {
    console.log(`${userName}, you are awesome`);
};

logName("Jane");

Из определения функции мы регистрируем любое заданное значение в сообщение Параметр к консоли. Затем мы назвали функцией с «Джейн, вы потрясающие!», Что напечатает этот текст на консоль.

При определении функции используя функциональные объявления, функция – подниматься Отказ Подъемная функция или переменная размещаются в верхней части их функциональной области, когда JavaScript выполняет код.

Примечание: Функциональный охват относится к тому, где была определена функция. Например, если функция foo () содержал функцию Бар () Внутри этого мы бы сказали, что функциональный объем Бар () это foo () Отказ Если foo () не был определен в функции, то foo () принадлежит к глобальному объему. Функции JavaScript в глобальном объеме доступны для всего кода, который работает с ним.

На практике это поведение позволяет использовать функцию, прежде чем определять ее. Например, предыдущий код может быть переписан так и будет вести себя так же:

logName();

function logName(name) {
    console.log(`${name}, you are awesome!`);
};

Функциональные выражения являются определениями функций, которые присваиваются переменной. Поэтому наше logname () Декларация функции может стать выражением функции, если мы создали это так:

const logUserName = function logName(name) {
    console.log(`${name}, you are awesome!`);
};

logUserName("Jane");

В этом примере, чтобы вызвать функцию, нам нужно использовать имя переменной, которое было предоставлено – Логосодержатель Отказ Это не изменяет поведение функции, оно все еще регистрирует «Вы потрясающие» на консоль.

В отличие от деклараций функций, функциональные выражения являются не поднимается. Эти функции доступны только в том случае, если переводчик JavaScript обрабатывает эту линейку кода.

Например, если мы пытались позвонить logusername () Перед созданием его функции выражение:

logUserName("Jane");
const logUserName = function logName(name) {
    console.log(`${name}, you are awesome!`);
};

Получаем следующую ошибку:

Uncaught ReferenceError: Cannot access 'logUserName' before initialization

Другая разность между выражениями функций и декларациями функций заключается в том, что выражения функций могут определять функции без имени.

Функции без имени называются Анонимные функции Отказ Например, logusername () также можно определить с такой анонимной функцией:

const logUserName = function (name) {
    console.log(`${name}, you are awesome!`);
};

Функции стрелки

Функции стрелки обеспечивают синтаксический сахар для выражений функций. Повторная реализация наших Логосодержатель Функция с использованием функции стрелки будет выглядеть так:

const logUserName = (name) => {
    console.log(`${name}, you are awesome!`);
}

Прочитайте функции стрелки в JavaScript, чтобы узнать больше об этом синтаксисе и как оно влияет на область функции.

Теперь, когда мы знаем, как создавать различные функции выражения, давайте узнаем, как сразу вызвать их.

Что сразу вызывают выражения функций?

IIFES являются функциями, которые выполняются сразу после быть определенным.

Мы можем сделать любую функцию экспрессию IIFE, обернув его в скобки и добавляя следующую пару скобок в конце:

(function() {
    // Code that runs in your function
})()

Кроме того, вы можете использовать синтаксис стрелки для создания iife следующим образом:

(() => {
    // Code that runs in your function
})()

Скобки, окружающие определение функции, позволяет JavaScript знает, что он будет обрабатывать функцию выражения. Последняя пара скобок вызывает функцию.

Вариации синтаксиса

Вы можете создавать iiFes без первого набора скобок, если вы используете оператор Unary – специальные символы, которые скажут JavaScript для оценки следующего выражения.

Мы можем создавать функциональные выражения с unary операторами, такими:

+function () {
    // Code that runs in your function
}();

-function () {
    // Code that runs in your function
}();

!function () {
    // Code that runs in your function
}();

~function () {
    // Code that runs in your function
}();

void function () {
    // Code that runs in your function
}();

Важно отметить, что эти операторы могут повлиять на любые данные, возвращаемые вашей функцией. Например, код ниже выглядит так, будто он должен вернуть 10 , но это на самом деле возвращает -10 :

$ node
> -function () {return 10;}();
-10
>

Поскольку этот унарный синтаксис менее распространен и может быть запутанному разработчикам, он обычно обескуражен.

IIFES также могут взять функциональные аргументы. Мы можем пропустить переменные в объем, как показано ниже:

(function(arg1, arg2) {
    // Code that runs in your function
})("hello", "world");

Теперь, когда мы видели, как создавать IIFES, давайте посмотрим на общие ситуации, когда они используются.

Когда использовать IIFE?

Наиболее распространенные случаи использования для IIFES являются:

  • Плиние глобальных переменных
  • Создание частных переменных и функций
  • Асинхронные функции в петлях

Плиние глобальных переменных

Если у вас есть 2 библиотеки, которые экспортируют объект с тем же именем, вы можете использовать IIFES, чтобы убедиться, что они не конфликтуют в вашем коде. Например, jquery и Наличными Библиотеки JavaScript оба экспорта $ как их главный объект.

Вы можете обернуть свой код в IIFE, который проходит один из глобальных переменных в качестве аргумента. Допустим, мы хотим убедиться, что $ относится к jquery объект, а не наличными Альтернатива. Вы можете убедиться, что jQuery используется со следующими IIFE:

(function($) {
    // Code that runs in your function
})(jQuery);

Создание частных переменных и функций

Мы можем использовать IFES для создания частных переменных и функций в глобальном объеме или любой другой области функции.

Функции и переменные, добавленные к глобальному объему, доступны для всех сценариев, которые загружаются на странице. Допустим, у нас была функция GenerateMagicNumber () , который вернул случайное число между 900 и 1000 включительно, и переменной Favoriteritumbumber в нашем файле JavaScript.

Мы можем написать их так:

function generateMagicNumber() {
    return Math.floor(Math.random() * 100) + 900;
}

console.log("This is your magic number: " + generateMagicNumber());

var favoriteNumber = 5;
console.log("Twice your favorite number is " + favoriteNumber * 2);

Если мы загрузим другие файлы JavaScript в нашем браузере, они также получают доступ к GenerateMagicNumber () и Favoriteritumbumber Отказ Чтобы они не могли их использовать или редактировать их, мы заключили наш код в IIFE:

(function () {
    function generateMagicNumber() {
        return Math.floor(Math.random() * 100) + 900;
    }

    console.log("This is your magic number: " + generateMagicNumber());

    var favoriteNumber = 5;
    console.log("Twice your favorite number is " + favoriteNumber * 2);
})();

Это проходит то же самое, но сейчас GenerateMagicNumber () и Favoriteritumbumber доступны только в нашем скрипте.

Асинхронные функции в петлях

Поведение JavaScript с удивлением многих, когда обратные вызовы выполняются в петлях. Например, давайте подсчитаем от 1 до 5 в JavaScript, выкладывая 1 второй разрыв между каждым временем, мы регистрируем сообщение. Наизывая реализация будет:

for (var i = 1; i <= 5; i++) {
    setTimeout(function () {
        console.log('I reached step ' + i);
    }, 1000 * i);
}

Если вы запустите этот код, вы получите следующий вывод:

$ node naiveCallbackInLoop.js
I reached step 6
I reached step 6
I reached step 6
I reached step 6
I reached step 6

Хотя вывод будет напечатан 1 секунду после другого, каждая строка печатает, что они достигли шага 6. Почему?

Когда JavaScript столкнулся с асинхронным кодом, он дефицит выполнение обратного вызова, пока асинхронная задача не завершится. Вот как это остается не блокировкой. В этом примере console.log () Заявление будет работать только после истечения тайм-аута.

JavaScript также создал закрытие для нашего обратного вызова. Закрытие – это сочетание функции и его объема Когда это было создано Отказ С закрытиями наш обратный вызов может получить доступ к переменной Я Несмотря на то, что для петля уже закончила выполнение.

Однако наш обратный вызов имеет доступ только к значению Я во время его исполнения Отказ Как код в пределах Setimeout () Функция все было отложено, для петля была закончена с Я быть равным 6. Вот почему все они входят в систему, что они достигли шага 6.

Эта проблема может быть решена с помощью IIFE:

for (var i = 1; i <= 5; i++) {
    (function (step) {
        setTimeout(function() {
            console.log('I reached step ' + step);
        }, 1000 * i);
    })(i);
}

Используя IIFE, мы создаем новый объем для нашей функции обратного вызова. Наша IIFE принимает параметр шаг Отказ Каждый раз, когда наша IIFE называется, мы даем ей текущую стоимость Я как его аргумент. Теперь, когда обратный вызов готов к выполнению, его закрытие будет иметь правильное значение шаг Отказ

Если мы запустим этот фрагмент кода, мы увидим следующий вывод:

$ node iifeCallbackInLoop.js
I reached step 1
I reached step 2
I reached step 3
I reached step 4
I reached step 5

Хотя IIFES решает нашу проблему с минимальными изменениями кода, давайте посмотрим, как функции ES6 могут облегчить запуск асинхронного кода в петлях.

Блок навес с пусть и const

ES6 добавил Пусть и Const Ключевые слова для создания переменных в JavaScript. Переменные объявлены с Пусть или Const являются блок-населенный Отказ Это означает, что они могут быть доступны только в их прилагающем блоке – область, заключенная в фигурных брекетах {} Отказ

Давайте сосчитать от 1 до 5 из 1 вторых интервалов, используя Пусть Ключевое слово вместо var :

for (let i = 1; i <= 5; i++) {
    setTimeout(function () {
        console.log('I reached step ' + i);
    }, 1000 * i);
}

Мы получим следующий вывод, когда мы запустим этот код:

$ node es6CallbackInLoop.js
I reached step 1
I reached step 2
I reached step 3
I reached step 4
I reached step 5

Теперь, когда переменная Я Обнаружено ли блок, закрытия для нашего обратного вызова, получают соответствующее значение Я когда они в конечном итоге выполняют. Это более лаконично, чем наша реализация IIFE.

Использование Пусть является предпочтительным способом выполнения асинхронных функций в петле,

Заключение

Непосредственное выражение функции (IIFE) – это функция, которая выполняется мгновенно после ее определения. Этот шаблон был использован для глобальных переменных псевдонима, делают переменные и функции частным и для обеспечения асинхронного кода в петлях выполнены правильно.

В то время как популярны, мы видели, как изменения в ES6 могут устранить необходимость использования IIFES в современном JavaScript. Тем не менее, овладение этой картины также дает нам более глубокое понимание охвата и закрытия и будет особенно полезно для поддержания устаревшего кода JavaScript.