Javascript, функції

При виклику функцій їм можуть передаватися значення, чи аргументи, що відповідатимуть їхнім параметрам. Функції часто використовують свої аргументи для обчислення значення, що повертається, яке є значенням вирази виклику функції. На додаток до аргументів при виклику будь-якої функції їй передається ще одне значення, що визначає контекст виклику - значення в ключовому слові this.

визначення функцій

Визначення функції починається з ключового слова function. за яким вказуються такі компоненти:

Ідентифікатор, що визначає ім'я функції

Пара круглих дужок навколо списку з нуля або більше ідентифікаторів, розділених комами

Ці ідентифікатори будуть визначати імена параметрів функції і в тілі функції можуть використовуватися як локальні змінні.

Ці інструкції складають тіло функції: вони виконуються при кожному виклику функції.

У наступному прикладі показано кілька визначень функцій у вигляді інструкцій і виразів. Зверніть увагу, що визначення функцій у вигляді виразів зручно використовувати, тільки якщо вони є частиною більш великих виразів, таких як присвоювання або виклик функції, які виконують деякі дії за допомогою знову оголошених функції:

Вираз визначення функції, навпаки, не оголошує змінну. Однак у виразах визначення допускається вказувати ім'я функції, як у функції обчислення факторіала вище, яке може знадобитися в тілі функції для виклику себе самої. Якщо вираз визначення функції включає ім'я, дане ім'я буде посилатися на об'єкт функції в області видимості цієї функції. Фактично ім'я функції стає локальної змінної, доступною тільки в тілі функції. У більшості випадків ім'я функції не потрібно вказувати в виразах визначення, що робить визначення більш компактними.

Зверніть увагу, що більшість (але не всі) функцій в прикладі містять інструкцію return. Інструкція return завершує виконання функції і виконує повернення значення свого вираження (якщо вказано) викликає програмі. Якщо вираз в інструкції return відсутня, вона повертає значення undefined. Якщо інструкція return відсутня в функції, інтерпретатор просто виконає всі інструкції в тілі функції і поверне викликає програмі значення undefined.

Більшість функцій в прикладі обчислюють деяке значення, і в них інструкція return використовується для повернення цього значення викликає програмі. Функція printprops () дещо відрізняється в цьому сенсі: її робота полягає в тому, щоб вивести імена властивостей об'єкта. Їй не потрібно повертати якесь значення, тому в функції відсутній інструкція return. Функція printprops () завжди буде повертати значення undefined. (Функції, які не мають значення, що повертається, іноді називаються процедурами.)

виклик функцій

Програмний код, який утворює тіло функції, виконується не в момент визначення функції, а в момент її виклику. Виклик функцій виконується за допомогою виразу виклику. Вираз виклику складається з виразу звернення до функції, яка повертає об'єкт функції, і наступними за ним круглими дужками із списком з нуля або більше виразів-аргументів, розділених комами, всередині.

Якщо вираз звернення до функції є виразом звернення до властивості - якщо функція є властивістю об'єкта або елементом масиву (тобто методом) - тоді вираз виклику є виразом виклику методу. У наступному фрагменті демонструється кілька прикладів виразів виклику звичайних функцій:

При виконанні функції обчислюються всі вирази-аргументи (зазначені між дужками), і отримані значення використовуються як аргументи функції. Ці значення присвоюються параметрам, імена яких перераховані у визначенні функції. У тілі функції вираження звернень до параметрів повертають значення відповідних аргументів.

При виклику звичайної функції повертається функцією значення стає значенням вирази виклику. Якщо повернення з функції відбувається після досягнення її кінця інтерпретатором, повертається значення undefined. Якщо повернення з функції відбувається в результаті виконання інструкції return, повертається значення виразу, наступного за інструкцією return, або undefined, якщо інструкція return не має вираження.

Метод - це не що інше, як функція, яка зберігається у вигляді властивості об'єкта. Якщо є функція func і об'єкт obj, то можна визначити метод об'єкта obj з ім'ям method, як показано нижче:

Найчастіше при виклику методів використовується форма звернення до властивостей за допомогою оператора точки, однак точно так же можна використовувати форму звернення до властивостей за допомогою квадратних дужок. Наприклад, обидві з таких висловів є виразами виклику методів:

Аргументи і повертається значення при виклику методу обробляються точно так же, як при виклику звичайної функції. Однак виклик методу має одна важлива відмінність: контекст виклику. Вираз звернення до властивості складається з двох частин: об'єкта (в даному випадку obj) і імені властивості (method). У подібних висловлюваннях виклику методів об'єкт obj стає контекстом виклику, і тіло функції отримує можливість посилатися на цей об'єкт за допомогою ключового слова this. наприклад:

Методи і ключове слово this займають центральне місце в парадигмі об'єктно-орієнтованого програмування. Будь-яка функція, яка використовується як метод, фактично отримує неявний аргумент - об'єкт, щодо якого вона була викликана. Як правило, методи виконують деякі дії з об'єктом, і синтаксис виклику методу наочно відображає той факт, що функція оперує об'єктом.

Аргументи і параметри функцій

необов'язкові аргументи

Коли число аргументів у виклику функції менше числа оголошених параметрів, яких бракує аргументи отримують значення undefined. Часто буває зручним писати функції так, щоб деякі аргументи були необов'язковими і могли опускатися при виконанні функції. У цьому випадку бажано передбачити можливість присвоювання досить розумних значень за замовчуванням параметрами, які можуть бути опущені. наприклад:

Списки аргументів змінної довжини

Якщо число аргументів у виклику функції перевищує число імен параметрів, функція позбавляється можливості напряму звертатися до неназваних значень. Вирішення цієї проблеми надає об'єкт Arguments. У тілі функції ідентифікатор arguments посилається на об'єкт Arguments, присутній у виклику. Об'єкт Arguments - це об'єкт, подібний масиву, який дозволяє добувати передані функції значення за їхніми номерами, а не по іменах.

Припустимо, що була визначена функція func, яка вимагає один аргумент x. Якщо викликати цю функцію з двома аргументами, то перший буде доступний всередині функції по імені параметра x або як arguments [0]. Другий аргумент буде доступний тільки як arguments [1]. Крім того, подібно справжнім масивів, arguments має властивість length, що визначає кількість містяться елементів. Тобто в тілі функції func, спричиненої з двома аргументами, arguments.length має значення 2.

Функції, подібні до цієї та здатні приймати довільне число аргументів, називаються функціями зі змінним числом аргументів (variadic functions, variable arity functions або varargs functions). Цей термін виник разом з появою мови програмування C.

Зверніть увагу, що функції зі змінним числом аргументів не повинні допускати можливість виклику з порожнім списком аргументів. Буде цілком розумним використовувати об'єкт arguments [] при написанні функції, яка чекає на отримати фіксований число обов'язкових іменованих аргументів, за якими може слідувати довільне число необов'язкових різних неназваних аргументів.

Не слід забувати, що arguments фактично не є масивом - це об'єкт Arguments. У кожному об'єкті Arguments є пронумеровані елементи масиву і властивість length, але з технічної точки зору це не масив. Краще розглядати його як об'єкт, що має деякі пронумеровані властивості.

Крім елементів свого масиву об'єкт Arguments визначає властивості callee і caller. При спробі змінити значення цих властивостей в строгому режимі ECMAScript 5 гарантовано збуджується виключення TypeError. Однак в нестрогому режимі стандарт ECMAScript стверджує, що властивість callee посилається на виконувану в даний момент функцію. Властивість caller не є стандартним, але воно присутнє у багатьох реалізаціях і посилається на функцію, що викликала поточну.

Властивість caller можна використовувати для доступу до стека викликів, а властивість callee особливо зручно використовувати для рекурсивного виклику різних неназваних функцій:

Властивості і методи функцій

властивість length

У тілі функції властивість arguments.length визначає кількість аргументів, переданих функції. Однак властивість length самої функції має інший зміст. Це властивість, доступне тільки для читання, повертає кількість аргументів, яке функція очікує отримати - число оголошених параметрів.

У наступному фрагменті визначається функція з ім'ям check (), яка отримує масив аргументів arguments від іншої функції. Вона порівнює властивість arguments.length (число фактично переданих аргументів) з властивістю arguments.callee.length (число очікуваних аргументів), щоб визначити, передано чи функції стільки аргументів, скільки вона очікує. Якщо значення не збігаються, генерується виняток. За функцією check () слід тестова функція func (), що демонструє порядок використання функції check ():

властивість prototype

Будь-яка функція має властивість prototype, що посилається на об'єкт, відомий як об'єкт прототипу. Кожна функція має свій об'єкт прототипу. Коли функція використовується в ролі конструктора, новостворений об'єкт успадковує властивості цього об'єкта прототипу.

Прототипи й властивість prototype обговорювалися в попередній статті.

Методи call () і apply ()

Методи call () і apply () дозволяють виконувати непрямий виклик функції, як якщо б вона була методом деякого іншого об'єкта. Першим аргументом обом методам, call () і apply (), передається об'єкт, щодо якого викликається функція; цей аргумент визначає контекст виклику і стає значенням ключового слова this в тілі функції. Щоб викликати функцію func () (без аргументів) як метод об'єкта obj, можна використовувати будь-яким з методів, call () або apply ():

Будь-який з цих способів виклику еквівалентний наступному фрагменту (де передбачається, що об'єкт obj не має властивості з ім'ям m):

У строгому режимі ECMAScript 5 перший аргумент методів call () і apply () стає значенням this, навіть якщо це просте значення, null або undefined. У ECMAScript 3 і в нестрогому режимі значення null і undefined заміщуються глобальним об'єктом, а просте значення - відповідним об'єктом-обгорткою.

Всі інші аргументи методу call (), наступні за першим аргументом, що визначає контекст виклику, передаються функції, що викликається. Метод apply () діє подібно методу call (), за винятком того, що аргументи для функції передаються у вигляді масиву. Якщо функція здатна обробляти довільне число аргументів, метод apply () може використовуватися для виклику такої функції в контексті масиву довільної довжини.

У наступному прикладі демонструється практичне застосування методу call ():

Метод bind ()

Метод bind () вперше з'явився в ECMAScript 5, але його легко імітувати в ECMAScript 3. Як випливає з його імені, основне призначення методу bind () полягає в тому, щоб зв'язати (bind) функцію з об'єктом. Якщо викликати метод bind () функції func і передати йому об'єкт obj, він поверне нову функцію. Виклик нової функції (як звичайної функції) виконає виклик оригінальної функції func як методу об'єкта obj. Будь-які аргументи, передані нової функції, будуть передані оригінальної функції. наприклад:

Такий спосіб зв'язування легко реалізувати в ECMAScript 3, як показано нижче:

Метод bind () в ECMAScript 5 не просто пов'язує функцію з об'єктом. Він також виконує часткове застосування: крім значення this пов'язані будуть всі аргументи, передані методу bind () після першого його аргументу. Часткове застосування - поширений прийом у функціональному програмуванні і іноді називається каррінг (currying).