Я замечаю, что в CoffeeScript, если я определяю функцию, используя:
a = (c) -> c=1
Я могу получить только выражение функции :
var a;
a = function(c) {
return c = 1;
};
Но лично я часто использую объявление функции , например:
function a(c) {
return c = 1;
}
Я использую первую форму, но мне интересно, есть ли в CoffeeScript способ создания объявления функции. Если такого способа нет, я хотел бы знать, почему CoffeeScript этого не делает. Я не думаю, что JSLint выдаст ошибку при объявлении, если функция объявлена в верхней части области видимости.
javascript
coffeescript
jslint
function-declaration
Грейс Шао
источник
источник
class
es.Ответы:
CoffeeScript использует объявления функций (также известные как «именованные функции») только в одном месте:
class
определениях. Например,class Foo
компилируется в
var Foo; Foo = (function() { function Foo() {} return Foo; })();
Причина, по которой CoffeeScript не использует объявления функций где-либо еще, согласно FAQ :
Вкратце: неосторожное использование объявлений функций может привести к несогласованности между IE (до 9) и другими средами JS, поэтому CoffeeScript избегает их.
источник
var a = function a() {};
). Объявления функций (напримерfunction a() {}
) не имеют таких межбраузерных несоответствийДа, ты можешь:
hello() `function hello() {` console.log 'hello' dothings() `}`
Вы избегаете чистого JS с помощью обратной кавычки `
Обратите внимание, что вы не можете делать отступ в теле функции.
Ура
источник
function updateSettings() {
; do -> dothings (),}
чтобы разрешить отступ. github.com/jashkenas/coffeescript/issues/…При работе с CoffeeScript следует помнить, что вы всегда можете вернуться к JavaScript. Хотя CoffeeScript не поддерживает объявления именованных функций, вы всегда можете вернуться к JavaScript, чтобы сделать это.
http://jsbin.com/iSUFazA/11/edit
# http://jsbin.com/iSUFazA/11/edit # You cannot call a variable function prior to declaring it! # alert csAddNumbers(2,3) # bad! # CoffeeScript function csAddNumbers = (x,y) -> x+y # You can call a named function prior to # delcaring it alert "Calling jsMultiplyNumbers: " + jsMultiplyNumbers(2,3) # ok! # JavaScript named function # Backticks FTW! `function jsMultiplyNumbers(x,y) { return x * y; }`
Вы также можете написать большую жирную функцию в CoffeeScript, а затем просто использовать трюк с обратными кавычками, чтобы JavaScript вызывал другую функцию:
# Coffeescript big function csSomeBigFunction = (x,y) -> z = x + y z = z * x * y # do other stuff # keep doing other stuff # Javascript named function wrapper `function jsSomeBigFunction(x,y) { return csSomeBigFunction(x,y); }`
источник
Нет, вы не можете определить функцию в сценарии кофе и заставить ее генерировать объявление функции в сценарии кофе.
Даже если вы просто напишете
-> 123
сгенерированный JS будет заключен в скобки, что сделает его функциональным выражением
(function() { return 123; });
Я предполагаю, что это происходит из-за того, что объявления функций «поднимаются» наверх охватывающей области видимости, что нарушает логический поток исходного кода coffeescript.
источник
Хотя это старый пост, я хотел добавить кое-что к разговору для будущих гуглеров.
OP верен в том, что мы не можем объявлять функции в чистом CoffeeScript (за исключением идеи использования обратных тиков для выхода из чистого JS внутри файла CoffeeScript).
Но что мы можем сделать, так это привязать функцию к окну и, по сути, получить то, что мы можем вызвать, как если бы это была именованная функция. Я не о том , это будет именованная функция, я обеспечиваю способ сделать то , что я полагаю , ОП хочет на самом деле сделать (вызвать функцию как Foo (пары) где - то в коде) с использованием чистого CoffeeScript.
Вот пример функции, прикрепленной к окну в coffeescript:
window.autocomplete_form = (e) -> autocomplete = undefined street_address_1 = $('#property_street_address_1') autocomplete = new google.maps.places.Autocomplete(street_address_1[0], {}) google.maps.event.addListener autocomplete, "place_changed", -> place = autocomplete.getPlace() i = 0 while i < place.address_components.length addr = place.address_components[i] st_num = addr.long_name if addr.types[0] is "street_number" st_name = addr.long_name if addr.types[0] is "route" $("#property_city").val addr.long_name if addr.types[0] is "locality" $("#property_state").val addr.short_name if addr.types[0] is "administrative_area_level_1" $("#property_county").val (addr.long_name).replace(new RegExp("\\bcounty\\b", "gi"), "").trim() if addr.types[0] is "administrative_area_level_2" $("#property_zip_code").val addr.long_name if addr.types[0] is "postal_code" i++ if st_num isnt "" and (st_num?) and st_num isnt "undefined" street1 = st_num + " " + st_name else street1 = st_name street_address_1.blur() setTimeout (-> street_address_1.val("").val street1 return ), 10 street_address_1.val street1 return
Это использует Google Адреса для возврата адресной информации для автоматического заполнения формы.
Итак, у нас есть партиал в приложении Rails, который загружается на страницу. Это означает, что модель DOM уже создана, и если мы вызовем указанную выше функцию при начальной загрузке страницы (до того, как вызов ajax отобразит фрагмент), jQuery не увидит элемент $ ('# property_street_address_1') (поверьте мне, это не было) т).
Поэтому нам нужно отложить google.maps.places.Autocomplete () до тех пор, пока элемент не появится на странице.
Мы можем сделать это с помощью обратного вызова Ajax при успешной загрузке партиала:
url = "/proposal/"+property_id+"/getSectionProperty" $("#targ-"+target).load url, (response, status, xhr) -> if status is 'success' console.log('Loading the autocomplete form...') window.autocomplete_form() return window.isSectionDirty = false
Итак, здесь, по сути, мы делаем то же самое, что вызываем foo ()
источник
Почему? Потому что объявление функции - зло. Посмотри на этот код
function a() { return 'a'; } console.log(a()); function a() { return 'b'; } console.log(a());
Что будет на выходе?
Если мы воспользуемся определением функции
var a = function() { return 'a'; } console.log(a()); a = function() { return 'b'; } console.log(a());
вывод:
источник
Попробуй это:
defineFct = (name, fct)-> eval("var x = function #{name}() { return fct.call(this, arguments); }") return x
Теперь будет напечатано «true»:
foo = defineFct('foo', ()->'foo') console.log(foo() == foo.name)
На самом деле я этим не пользуюсь, но иногда мне хочется, чтобы кофейные функции имели имена для самоанализа.
источник