Function

Блок кода для вызова
из любого места программы

Функцию нужно определить, а затем вызывать.

Синтаксис определения функции

Существует 3 основных синтаксиса:

  • Function Declaration
  • Function Expression
  • Arrow Function изучим позже

Function declaration

  • Служебное слово function
  • Имя name - глагол
  • Объявление локальных переменных блока (parametrs)
  • Блок
  • Точка с запятой не обязательна

c параметрами
function add (a, b) {
    return a + b; 
}

без параметров
function hello () {
    console.log('Hello') 
}

                

Не стандартизованное свойство name

 
function add (a, b) {
    return a + b; 
}

add.name add                        
                    

Function expression

Точка с запятой обязательна

Это функция, которая присваивается переменной. Синтаксис бывает 2-х видов - с именем функции и без имени.

Собственное имя не обязательно - его нельзя использовать нигде, кроме как в теле функции для рекусии

 
let sum = 0;
const add = 
  function adding(n) {
  sum += n;
  if(n >= 1) adding(n-1);
}
add(5); 15                          
                    

Именованная функция­-выражение


const add = 
 function add (a, b) {
        return a + b; 
 };                    
                

Анонимная функция­-выражение


const add = 
 function (a, b) {
        return a + b; 
 };                    
                

Синтаксис вызова функции

Функция вызывается 4 разными способами:

  • как функция
  • как метод изучим позже
  • как конструктор изучим позже
  • комбинация - вызвать метод как функцию и наоборотизучим позже

Вызов функции состоит из имени функции и обязательных круглых скобок с перечислением аргументов ().


add(2, 3) 5                    
hello() hello                    
                

Аргументы

Количество аргументов может отличаться от количества параметров - это не вызовет ошибки.

Если параметр объявлен в теле функции, а при вызове аргумент не присвоен, то локальной переменной будет присвоен undefined

Если undefined не желателен, то стоит задать значения по умолчанию.

Значения по умолчанию для параметров.

Old school :


function add (a, b) {
    let x = a || 2;
    let y = b || 3;
    return x + y; 
};  
add();  5
                

ES5 :


function add (a = 2, b = 3) {
    return a + b; 
};  
add();  5
                

Псевдомассив arguments

Порядок объявления аргументов имеет значение:

 
function diving (a, b) {
  return a / b
}
 diving (4, 2)2
 diving (2, 4).5                    
                

Как достигается гарантия порядка? С помощью псевдомассива arguments

В каждой функции при вызове создается псевдомассив с именем arguments. Этот псевдомассив доступен для чтения.


function getLastArg () {
  let max = 
    arguments.length - 1;
  return arguments[max];
}
getLastArg(1, 5, "last") 
"last"               
            

Его можно использовать. Например получим функцию, суммирующую любое количество аргументов:


function summator () {
  let sum = 0;
  let max = 
    arguments.length;
  for (
        let i = 0; 
        i < max; 
        i += 1
      ) {
    sum += arguments[i]
  }
  return sum;
}
summator(1, 2, 3, 4, 5)    
15             
            

Подъем функций

FD vs FE

Особенностью Function Declaration является то, что такую функцию можно вызывать до объявления

Выполнение кода JS происходит в два этапа. На первом этапе компилятор исследует код и собирает объявление функция (FD) и объявленные переменные. На втором этапе происходит вызов функций и вычисление/присвоение переменных. Таким образом переменные оказываются вверху области видимости со значеним undefined. Функции FE присвоены переменным, но в начале кода этим переменным пока не присвоена функция. FE не могут выполняться. А функций FD уже готовы к выполнению фактически до объявления.

 
var foo = 1; 

function bar() { 
  var foo; // undefined 
  if (!foo) { // true
    var foo = 10; 
  } 
    return foo;
} 
bar(); //10 true                    
                
code first circle seconde circle

Возврат значения

void vs return

void - функция, которая не возвращает результат, а изменяет что-либо вне функции. Служебное слово void зарезервировано, но не используется. Достаточно не использовать return


let a;

function set(num) {
    a = [num];
}

set(10);
Array.isArray(a) true
a[0] 10 
                    

return - функция, которая возвращает результат в место вызова. Использует служебное слово return


let a;

function set(num) {
    return [num]
}
    
a = set(10);
Array.isArray(a) true
a[0] 10                      
                    

Чистые функции

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

Если есть выбор - используйте чистые функции. Их легко тестировать и можно переиспользовать не рискуя побочными эффектами.

Создать программу из одних чистых функций невозможно - как минимум требуется вывести результат. Но стремиться к этому надо :-)

Две главные особенности функций

Функции – это ссылочный тип

  • Функции могут создаваться динамически
    
    const sum = 
        new Function(
            'a', 
            'b', 
            'return a + b'
        );
    sum(2, 3) 5
    
                                
  • Функции могут присваиваться переменным
  • 
    const arr = [
     function (a, b) {
         return a + b;
     },
     function (a, b) {
        return a * b;
     }
    ];             4
    
    const sum = arr[0]
    const mult = arr[1]
    
    sum(2, 3)  5
    mult(2, 3)  6
                            
  • Функции могут передаваться как аргументы другим функциям
    
    function doIt(fn, a, b){
      return fn(a, b)
    }
    
    function sum(a, b) {
      return a + b;
    }
    
    doIt(sum, 2, 3) 5
    
    
                                
    и могут возвращаться другими функциями
    
    function calc(sign) {
      return new Function(
        'a', 
        'b', 
        `return a ${sign} b`
        )
    }
    
    let sum = calc("+")
    
    sum(2, 3) 5
    
                                
  • Функции могут иметь собственные свойства и методы об этом позже

Стек вызовов

Функция при вызове помещается в стек. Затем результат вычисления возвращается в стек в то самое место очереди, откуда призошел вызов.


function baz() {
    console.log('baz')
}    

function bar() {
    console.log('bar')
}      
    
function foo () {

   console.log('foo')
   bar()
   baz()
}


foo()                    
                
stack