У меня есть мнение (которое, я уверен, некоторые поделятся), что передача анонимных функций, которые содержат более нескольких строк кода, в качестве аргументов для других функций сильно влияет на читабельность и самодокументирование до такой степени, что, как мне кажется, это будет гораздо лучше для любого, кто использует код для объявления именованной функции. Или, по крайней мере, присвойте эту анонимную функцию переменной, прежде чем объявить основную функцию
Однако многие библиотеки JavaScript (jQuery, d3.js / NVD3.js) просто для того, чтобы привести пару примеров, используют большие функции таким образом.
Почему это так широко распространено в JavaScript? Это культурная вещь, или есть какие-то преимущества, которые я упускаю, которые сделали бы использование более предпочтительным, чем объявление именованной функции?
источник
public
иprivate
обходные пути для не имеющих надлежащего закрытия.Ответы:
Три основные причины, которые я могу придумать:
Доступ к родительской области: определения встроенных функций позволяют встроенному коду иметь доступ к переменным, определенным в родительских областях. Это может быть очень полезно для многих вещей и может уменьшить объем или сложность кода, если все сделано правильно.
Если вы поместите код в функцию, определенную за пределами этой области, а затем вызовете код, вам придется передать любое родительское состояние, к которому он хочет получить доступ к функции.
Конфиденциальность: код внутри встроенного анонимного определения является более закрытым и не может быть вызван другим кодом.
Сокращение имен, определенных в более высоких областях: это наиболее важно при работе в глобальной области, но встроенное анонимное объявление не требует определять новый символ в текущей области. Поскольку Javascript изначально не требует использования пространств имен, разумно избегать определения более глобальных символов, чем это требуется минимально.
От редакции. Кажется, что это стало культурным явлением в Javascript, когда объявление чего-то анонимно встроенным почему-то считается «лучше», чем определение функции и ее вызов, даже если доступ к родительской области не используется. Я подозреваю, что это было первоначально из-за глобальной проблемы загрязнения пространства имен в Javascript, затем, возможно, из-за проблем конфиденциальности. Но теперь это превратилось в нечто культурное, и вы можете увидеть это во многих открытых частях кода (например, тех, которые вы упоминаете).
В таких языках, как C ++, большинство из них, вероятно, сочли бы нереальной практикой иметь одну гигантскую функцию, которая распространяется на многие страницы / экраны. Конечно, C ++ имеет встроенное пространство имен, не обеспечивает родительский доступ к области и имеет функции конфиденциальности, поэтому его можно полностью мотивировать удобочитаемостью / возможностью сопровождения, тогда как Javascript должен использовать выражение кода для достижения конфиденциальности и доступа к родительской области. Таким образом, JS, похоже, мотивируется в другом направлении, и это становится чем-то культурным в языке, даже когда вещи, которые мотивировали это направление, не нужны в конкретном случае.
источник
Анонимные функции используются для JavaScript в гораздо большем количестве целей, чем в большинстве языков.
Во-первых, они используются для пространств имен и определения области блоков. До недавнего времени в JavaScript отсутствовали модули или какой-либо другой механизм пространства имен, который привел к использованию анонимных функций для предоставления этих функций через шаблон модуля. Называть эти функции абсолютно бесполезно. В меньшем масштабе, из-за отсутствия в Scople блока JavaScript до недавнего времени, подобный шаблон использовался для имитации области блока; наиболее заметно в теле петель. Использование именованной функции в этом случае будет активно запутывать.
Во-вторых, и менее специфичные для JavaScript анонимные функции часто используются с функциями более высокого порядка, которые имитируют управляющие структуры. Например,
each
метод jQuery . Я сомневаюсь, что вы абстрагируете каждое тело цикла или if-ответвления в функцию, если она длиннее нескольких строк. Та же самая логика применяется в этом случае.Последняя причина заключается в том, что программирование на основе событий является распространенным явлением в JavaScript, что приводит к непреднамеренному кодированию стиля передачи продолжения . Вы делаете AJAX-вызов и регистрируете обратный вызов, который при выполнении делает еще один AJAX-вызов и регистрирует обратный вызов и т. Д. Если бы вызовы были синхронными, а не асинхронными, это была бы просто прямолинейная последовательность кода в одной лексической области , Опять же, я сомневаюсь, что вы бы абстрагировали каждые несколько строк прямого кода в функцию.
Существуют также культурные факторы, и по вышеуказанным причинам анонимные функции в JavaScript встречаются гораздо чаще, чем во многих других языках, и используются более комфортно / слабо, чем во многих других языках.
источник