Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Function Declaration и Function Expression

Лекция



Привет, сегодня поговорим про function declaration, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое function declaration, function expression , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend).


  1. Объявление Function Declaration
    1. Время создания Function Declaration
  2. Объявление Function Expression
  3. Функция с вызовом «на месте»
    1. Зачем скобки вокруг функции?
  4. Итого

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

Объявление Function Declaration

Объявление функции, о котором мы говорили все время до этого, называется в спецификации языкаFunction Declaration.

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

Позвольте еще раз выделить основной смысл объявления Function Declaration:

 

При объявлении функции создается переменная со значением-функцией

Другими словами, объявление function func(параметры) { код } говорит интерпретатору: «создай переменную func, и положи туда функцию с указанными параметрами и кодом».

При этом func — на самом деле не «имя функции». Оно совсем никак не привязано к функции!

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

 

   
1 function func() { alert(1); }
2  
3 var g = func; // скопировали
4  
5 func = null;  // поменяли значение
6  
7 g(); // работает, теперь функция в g, а в func ничего нет
8 func(); // вызываем null()? ошибка!

 

 

В частности, невозможно иметь функцию и переменную с одинаковым именем:

 

   
1 // Нонсенс!
2 function f() { } // объявить переменную f и записать в нее функцию
3 var f = 5; // объявить переменную f (а она уже объявлена) и присвоить 5
4  
5 alert(f); // результат: 5

 

В примере выше переменная f в первой строке получает значение — функцию, а во второй — число 5. В итоге мы получим переменную со значением f=5.

Время создания Function Declaration

Функции, объявленные как Function Declaration, создаются интерпретатором до выполнения кода.

Перед тем, как выполнять первую строку, интерпретатор сканирует код, ищет в немFunction Declaration и обрабатывает их.

Поэтому их можно вызвать до объявления, например:

 

   
1 sayHi("Вася");
2  
3 function sayHi(name) {
4   alert("Привет, " + name);
5 }

 

Этот код будет работать, т.к. объявление function sayHi обрабатывается и функция создается до выполнения первой строчки кода.

Условно объявить функцию через Function Declaration нельзя

Попробуем, в зависимости от условия, объявить функцию по-разному:

 

   
1 var age = 20;
2  
3 if (age >= 18) {
4   function sayHi() {  alert('Прошу вас!');  }
5 else {
6   function sayHi() {  alert('До 18 нельзя'); }
7 }
8  
9 sayHi();

 

Какой вызов сработает?

Чтобы это понять — вспомним, как работают функции.

  1. Function Declaration обрабатываются до выполнения первой строчки кода.

    Браузер сканирует код и создает из таких объявлений функции. При этом второе объявление перезапишет первое.

  2. Дальше, во время выполнения объявления игнорируются (они уже обработаны), как если бы код был таким:
    01 function sayHi() {  alert('Прошу вас!');  }
    02 function sayHi() {  alert('До 18 нельзя'); }
    03  
    04 var age = 20;
    05  
    06 if (age >= 18) {
    07     
    08 else {
    09    
    10 }
    11  
    12 sayHi();

Как видно, конструкция if здесь ни на что не влияет. Об этом говорит сайт https://intellect.icu . По-разному объявить функцию, в зависимости от условия, не получилось.

P.S. Это — правильное с точки зрения спецификации поведение. На момент написания этого раздела ему следуют все браузеры, кроме Firefox.

 

Объявление Function Expression

Существует альтернативный синтаксис для создания функций, который решает проблемы с «условным» объявлением.

Функцию можно создать и присвоить переменной как самое обычное значение.

Такое объявление называется Function Expression и выглядит так:

 

   
1 var f = function(параметры) {
2    // тело функции
3 };

 

Например:

 

   
1 var sayHi = function(person) {
2     alert("Привет, " + person);
3 };
4  
5 sayHi('Вася');

 

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

Например, вполне допустимо такое объявление массива:

 

   
1 var arr = [1, 2, function(a) { alert(a) }, 3, 4];
2  
3 var fun = arr[2];
4 fun(1); // 1

 

В отличие от объявлений Function Declaration, которые создаются заранее, до выполнения кода, объявления Function Expression создают функцию, когда до них доходит выполнение.

Поэтому и пользоваться ими можно только после объявления.

 

   
1 sayHi(); // <-- работать не будет, функции еще нет
2  
3 var sayHi = function() {  alert(1)  };

 

… А вот так — будет:

   
1 var sayHi = function() {  alert(1)  };
2  
3 sayHi(); // 1

 

Благодаря этому свойству Function Expression можно (и даже нужно) использовать для условного объявления функции:

 

   
01 var age = prompt('Сколько вам лет?');
02 var sayHi;
03  
04 if (age >= 18) {
05   sayHi = function() {  alert('Вход разрешен');  }
06 else {
07   sayHi = function() {  alert('Извините, вы слишком молоды');  }
08 }
09  
10 sayHi(); // запустит ту функцию, которая присвоена в if

 

Функция с вызовом «на месте»

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

Наш скрипт настолько замечательный, что мы хотим дать его другим людям.

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

Чтобы его не было, нашему скрипту нужна своя отдельная область видимости, в которой он будет работать.

Для этого используют функции с вызовом «на месте». Такая функция объявляется — и тут же вызывается, вот так:

1 (function() {
2  
3   var a = 1 , b = 2; // переменные для нашего скрипта
4  
5   // код скрипта
6  
7 })();

 

Теперь внутренние переменные скрипта стали локальными. Даже если в другом месте страницы объявлена своя переменная a — проблем не будет. Наш скрипт теперь имеет свою, изолированную область видимости.

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

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

Зачем скобки вокруг функции?

В примерах выше вокруг function() {...} находятся скобки. Если записать без них — такой код вызовет ошибку:

 

   
1 function() {
2  // syntax error
3 }();

 

Эта ошибка произойдет потому, что браузер, видя ключевое слово function в основном потоке кода, попытается прочитать Function Declaration, а здесь даже имени нет.

Впрочем, даже если имя поставить, то работать тоже не будет:

   
1 function work() {
2   // ...
3 }();  // syntax error

 

Дело в том, что «на месте» разрешено вызывать только Function Expression.

Общее правило таково:

  • Если браузер видит function в основном потоке кода - он считает, что этоFunction Declaration.
  • Если же function идет в составе более сложного выражения, то он считает, что этоFunction Expression.

Для этого и нужны скобки - показать, что у нас Function Expression, который по правилам JavaScript можно вызвать «на месте».

Можно показать это другим способом, например поставив перед функцией оператор:

   
1 +function() {
2   alert('Вызов на месте');
3 }();
4  
5 !function() {
6   alert('Так тоже будет работать');
7 }();

 

Главное, чтобы интерпретатор понял, что это Function Expression, тогда он позволит вызвать функцию «на месте».

Скобки не нужны, если это и так Function Expression, например в таком вызове:

 

   
1 // функция объявлена и тут же вызвана
2 var res = function(a,b) { return a+b }(2,2);
3 alert(res); // 4

 

Функция здесь создается как часть выражения присваивания, поэтому является Function Expressionи может быть вызвана «на месте». При этом, так как сама функция нигде не сохраняется, то она исчезнет, выполнившись, останется только ее результат.

 

При вызове «на месте» лучше ставить скобки и для Expression

Технически, если функция и так задана как Function Expression, то она может быть вызвана «на месте» без скобок:

 

var result = function(a,b) {
  return a*b;
}(2,3);

 

Но из соображений стиля и читаемости скобки вокруг function рекомендуется ставить:

 

var result = (function(a,b) {
  return a*b;
})(2,3);

 

Тогда сразу видно, что в result записывается не сама функция (result = function...), а идет «вызов на месте». При чтении такого кода меньше ошибок.

 

Итого

Функции в JavaScript являются значениями. Их можно присваивать, передавать, создавать в любом месте кода.

  • Если функция объявлена в основном потоке кода, то это Function Declaration.
  • Если функция создана как часть выражения, то это Function Expression.

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

 Function DeclarationFunction Expression
Время создания До выполнения первой строчки кода. Когда управление достигает строки с функцией.
Можно вызвать до объявления Да (т.к. создается заранее) Нет
Можно объявить в if Нет (т.к. создается заранее) Да
Можно вызывать «на месте» Нет (ограничение синтаксиса JavaScript) Да

Как общий совет — предпочитайте Function Declaration.

Сравните по читаемости:

1 // Function Expression
2 var f = function() { ... }
3  
4 // Function Declaration
5 function f() { ... }

 

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

Используйте Function Expression только там, где это действительно нужно. Например, для объявления функции в зависимости от условий.

К сожалению, в одной статье не просто дать все знания про function declaration. Но я - старался. Если ты проявишь интерес к раскрытию подробностей,я обязательно напишу продолжение! Надеюсь, что теперь ты понял что такое function declaration, function expression и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)

создано: 2014-10-07
обновлено: 2024-11-14
243



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)

Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)