80 votes

Déclaration de fonction en CoffeeScript

Je remarque que dans CoffeeScript, si je définir une fonction à l'aide de:

a = (c) -> c=1

Je ne peut obtenir l' expression de fonction:

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

Mais, personnellement, j'utilise souvent la fonction de déclaration,par exemple:

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

J'utilise la première forme, mais je me demandais si il existe un moyen en CoffeeScript la génération d'une déclaration de fonction. Si il n'y a aucun moyen, je voudrais savoir pourquoi CoffeeScript éviter de le faire. Je ne pense pas que JSLint hurlaient d'une erreur de déclaration, tant que la fonction est déclarée dans le haut de la portée.

61voto

Trevor Burnham Points 43199

CoffeeScript utilise les déclarations de fonction (aka "les fonctions nommées") qu'à un seul endroit: class définitions. Par exemple,

class Foo

compile de

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

La raison CoffeeScript ne pas utiliser la fonction déclarations ailleurs, selon la FAQ:

Blâmer Microsoft pour celui-ci. A l'origine, chaque fonction qui pourrait avoir un nom judicieux récupérées pour lui a été donné un, mais les versions IE 8 et bas de délimitation de l'étendue des problèmes où le nom de fonction est considérée à la fois comme une déclaration et d'une expression. Voir ce pour plus d'informations.

En bref: à l'Aide de déclarations de fonction négligemment peut mener à des incohérences entre IE (pré-9) et d'autres JS environnements, de sorte CoffeeScript évite.

12voto

Zaid Daghestani Points 4142

Oui, vous pouvez:

hello()

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

- Vous échapper à la pure JS via le backtick `

Notez que vous ne pouvez pas le retrait de votre corps de la fonction.

Cheers

6voto

mattmc3 Points 6768

Une chose à garder à l'esprit avec CoffeeScript est que vous pouvez toujours vous détendre au JavaScript. Alors que CoffeeScript ne supporte pas nommé les déclarations de fonction, vous pouvez toujours revenir à JavaScript pour le faire.

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

Vous pouvez également écrire un big fat fonction en CoffeeScript puis il suffit d'utiliser les backticks astuce pour avoir JavaScript appel de la fonction:

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

1voto

AngusC Points 381

Non, vous ne pouvez pas définir une fonction dans le café de script et de faire générer une déclaration de fonction dans le café script

Même si vous venez d'écrire

-> 123

la JS généré sera enveloppé dans les parenthèses, ce qui en fait une expression de fonction

(function() {
  return 123;
});

Je suppose que c'est parce que les déclarations de fonction get "hissé" en haut du cadre englobant qui permettrait de briser la logique de la coffeescript source.

1voto

notaceo Points 161

Alors que c'est un vieux post, je voulais ajouter quelque chose à la conversation pour l'avenir Googlers.

L'OP est correct que nous ne pouvons pas déclarer des fonctions dans le plus pur CoffeeScript (à l'exclusion de l'idée de l'utilisation de l'arrière-tiques pour échapper à la pure JS à l'intérieur de la CoffeeScript fichier).

Mais ce que nous pouvons faire est de lier la fonction de la fenêtre, et essentiellement de la fin de quelque chose qu'on peut l'appeler comme si c'était un nom de fonction. Je ne suis pas à l'indiquer, est un nom de fonction, je suis en fournissant un moyen de faire ce que j'imagine de l'OP veut réellement faire (appel d'une fonction comme foo(param) quelque part dans le code) à l'aide de pure CoffeeScript.

Voici un exemple d'une fonction attachée à la fenêtre en 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

C'est à l'aide de Google Places à l'adresse de retour d'informations pour remplir automatiquement un formulaire.

Nous avons donc une partielle dans une application Rails, qui est chargé dans une page. Cela signifie que le DOM est déjà créé, et si nous appelons la fonction ci-dessus sur le chargement initial de la page (avant l'appel ajax rend l'partielle), jQuery ne verrez pas le $('#property_street_address_1') de l'élément (croyez-moi - il n'a pas).

Nous avons donc besoin de retarder la google.cartes.des lieux.La saisie semi-automatique() jusqu'à ce que l'élément est présent sur la page.

On peut le faire via l'Ajax de rappel sur le succès de la charge de la partielle:

            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

Donc, ici, essentiellement, nous faisons la même chose que d'appeler foo()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X