Чому передача великих анонімних функцій як аргументів іншим функціям так широко прийнята в JavaScript?


27

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

Однак багато бібліотек JavaScript (jQuery, d3.js / NVD3.js) просто для того, щоб надати пару прикладів, використовують великі функції таким чином.

Чому це так широко прийнято в JavaScript? Це культурна річ, чи є ті переваги, які мені не вистачають, що зробило б використання кращим, ніж оголошення оголошеної функції?


1
Це, мабуть, має багато спільного з використанням закривань . Це також може бути пов'язане з тим, що не хочеться піддавати фактичну функцію зовнішньому світу (саме тому вона є анонімною).
Роберт Харві

3
@RobertHarvey Іншими словами, це спосіб вирішити, що JavaScript не має публічного та приватного ?
Мейсон Вілер

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

5
@MasonWheeler: Це залежить від вашої точки зору. Програміст схеми або ECMAScript може сказати, що це publicі privateє обхідними шляхами для недостатнього закриття.
Йорг W Міттаг

1
@ JörgWMittag Hooray for Racket, офіційний мовний спонсор XKCD 927!
Мейсон Уілер

Відповіді:


23

Три головні причини, про які я можу придумати:

  1. Доступ для батьків
  2. Конфіденційність
  3. Скорочення імен, визначених у вищих масштабах

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

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

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

Скорочення імен, визначених у вищих масштабах : Це найважливіше під час роботи в глобальному масштабі, але вбудована анонімна заява утримує від необхідності визначення нового символу в поточному масштабі. Оскільки Javascript не вимагає використання просторів імен, то розумно уникати визначення більш глобальних символів, ніж мінімально необхідних.


Редакція: Схоже, це стало культурною річчю в Javascript, де декларування чогось анонімного вбудованого якимось чином вважається «кращим», ніж визначення функції та виклик її навіть тоді, коли доступ до батьківських областей не використовується. Я підозрюю, що це було спочатку через глобальну проблему забруднення простору імен у Javascript, потім, можливо, через проблеми конфіденційності. Але це тепер перетворилося на якусь культурну річ, і ви можете бачити, що це виражається у багатьох публічних кодексах (на кшталт тих, які ви згадуєте).

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


Оскільки нещодавно розробник C ++ перейшов до JS протягом більшої роботи, ця відповідь має багато сенсу, особливо «точка доступу батьківських областей» - вона дійсно має можливість значно спростити ваш код. Один нітроподібний - C ++ забезпечує батьківський доступ до сфери доступу в C ++ 11 лямбдах :) Хоча, безумовно, +1.
Командир Коріандр Саламандра

8

Анонімні функції використовуються в JavaScript набагато більше, ніж на більшості мов.

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

По-друге, і менш специфічні для JavaScript, анонімні функції часто використовуються з функціями вищого порядку, що імітують структури управління. Наприклад, eachметод jQuery . Я сумніваюся, що ви абстрагуєте кожне тіло циклу чи if-гілку у функції, коли це довше, ніж кілька рядків. Ця ж логіка застосовується і в цьому випадку.

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

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


Мої власні, можливо, наївні структури в кодуванні C ++ іноді брали принципи кодування на основі подій та зворотних викликів з JavaScript через std :: function та lambdas. У моєму випадку це частково тому, що я роблю UI-код у C ++ і не хочу виконувати операції блокування. Мені цікаво, якщо практики JavaScript просто корисні для будь-кого, доки мова їх добре підтримує.
Katana314
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.