Deklaracja funkcji w CoffeeScript

Zauważam, że w CoffeeScript, jeśli zdefiniuję funkcję używając:

a = (c) -> c=1

Mogę uzyskać tylko wyrażenie funkcji :

var a;
a = function(c) {
    return c = 1;
};

Ale osobiście często używam deklaracji funkcji , na przykład:

function a(c) {
    return c = 1;
}

Używam pierwszej formy, ale zastanawiam się, czy istnieje sposób w CoffeeScript generowania deklaracji funkcji. Jeśli nie ma takiej możliwości, chciałbym wiedzieć, dlaczego CoffeeScript tego nie robi. Nie sądzę, żeby JSLint wykrzyczał błąd przy deklaracji, tak długo, jak funkcja jest zadeklarowana na górze zakresu.

Author: Grace Shao, 2011-07-01

7 answers

CoffeeScript używa deklaracji funkcji (aka "nazwane funkcje") w jednym miejscu: class definicje. Na przykład,

class Foo

Kompiluje do

var Foo;
Foo = (function() {
  function Foo() {}
  return Foo;
})();

Powód, dla którego CoffeeScript nie używa deklaracji funkcji gdzie indziej, zgodnie z FAQ :

/ Align = "center" bgcolor = "# e0ffe0 " / Cesarz Japonii / / align = center / Pierwotnie każda funkcja, która mogła mieć sensowną nazwę dla niej została podana, ale wersje IE 8 i down mają problemy z zakresami, gdzie nazwana funkcja jest traktowana jako zarówno deklaracja, jak i wyrażenie. Zobacz to aby uzyskać więcej informacji.

W skrócie: niedbałe używanie deklaracji funkcji może prowadzić do niespójności między IE (pre-9) a innymi środowiskami JS, więc CoffeeScript unika ich.

 60
Author: Trevor Burnham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-01 15:32:01

Yes you can:

hello()

`function hello() {`
console.log 'hello'
dothings()
`}`

Uciekasz z czystego JS przez backtick '

Zauważ, że nie możesz wciąć na swoim ciele funkcji.

Cheers

 12
Author: Zaid Daghestani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-25 00:38:02

Jedną rzeczą, o której należy pamiętać w coffeescript, jest to, że zawsze możesz wrócić do JavaScript. Chociaż CoffeeScript nie obsługuje nazwanych deklaracji funkcji, zawsze możesz wrócić do JavaScript, aby to zrobić.

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; }`

Możesz również napisać funkcję big fat w CoffeeScript, a następnie użyć sztuczki backticks, aby JavaScript wywołał inną funkcję:

# 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); }`
 6
Author: mattmc3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-27 19:41:53

Nie, Nie można zdefiniować funkcji w skrypcie coffee i zmusić ją do wygenerowania deklaracji funkcji w skrypcie coffee

Nawet jeśli tylko napiszesz

-> 123

Wygenerowany JS będzie zawinięty w parens, co uczyni go wyrażeniem funkcji

(function() {
  return 123;
});

Domyślam się, że dzieje się tak dlatego, że deklaracje funkcji są "podnoszone" na górę zakresu, co zaburzyłoby logiczny przepływ źródła coffeescript.

 1
Author: AngusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-13 18:18:00

Chociaż jest to starszy post, chciałem dodać coś do rozmowy dla przyszłych Googlerów.

OP jest poprawne w tym, że nie możemy zadeklarować funkcji w czystym CoffeeScript (wyłączając pomysł użycia back-ticksów do ucieczki czystego JS wewnątrz pliku CoffeeScript).

Ale to, co możemy zrobić, to powiązać funkcję z oknem i zasadniczo skończyć z czymś, co możemy wywołać tak, jakby to była funkcja o nazwie. Nie stwierdzam, że jest funkcją nazwaną, podaję sposób aby zrobić to, co wyobrażam sobie OP chce faktycznie zrobić(wywołać funkcję taką jak foo (param) gdzieś w kodzie) za pomocą czystego CoffeeScript.

Oto przykład funkcji dołączonej do okna w 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

Jest to użycie Google Places, aby zwrócić informacje o adresie, aby automatycznie wypełnić formularz.

Mamy więc część w aplikacji Rails, która jest ładowana do strony. Oznacza to, że DOM jest już utworzony, a jeśli wywołamy powyższą funkcję przy początkowym wczytaniu strony (przed wywołanie ajax renderuje częściowy), jQuery nie zobaczy elementu $('#property_street_address_1') (zaufaj mi - nie).

Więc musimy opóźnić google.mapy.miejsca.Autocomplete () dopóki element nie pojawi się na stronie.

Możemy to zrobić poprzez wywołanie zwrotne Ajax przy pomyślnym załadowaniu częściowego:

            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

Więc tutaj, zasadniczo, robimy to samo, co wywołanie foo ()

 1
Author: notaceo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-09 16:34:48

Dlaczego? Ponieważ deklaracja funkcji jest zła. Spójrz na ten kod

function a() {
        return 'a';
}

console.log(a());

function a() {
        return 'b';
}

console.log(a());

Co będzie na wyjściu?

b
b

Jeśli użyjemy definicji funkcji

var a = function() {
        return 'a';
}

console.log(a());

a = function() {
        return 'b';
}

console.log(a());

Wyjście to:

a
b
 1
Author: Tomasz Jakub Rup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-02 15:04:28

Spróbuj tego:

defineFct = (name, fct)->
  eval("var x = function #{name}() { return fct.call(this, arguments); }")
  return x

Teraz drukuje "true":

foo = defineFct('foo', ()->'foo')
console.log(foo() == foo.name)

Nie używam tego, ale czasami chciałbym, aby funkcje kawy miały nazwy dla introspekcji.

 0
Author: shaunc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-21 01:05:44