Ich stelle fest, dass in CoffeeScript, wenn ich eine Funktion definiere, indem ich:
a = (c) -> c=1
Ich kann nur den Funktionsausdruck bekommen :
var a;
a = function(c) {
return c = 1;
};
Ich persönlich verwende jedoch häufig eine Funktionsdeklaration , zum Beispiel:
function a(c) {
return c = 1;
}
Ich verwende zwar das erste Formular, frage mich jedoch, ob es in CoffeeScript eine Möglichkeit gibt, eine Funktionsdeklaration zu generieren. Wenn es keinen solchen Weg gibt, würde ich gerne wissen, warum CoffeeScript dies vermeidet. Ich glaube nicht, dass JSLint einen Fehler bei der Deklaration auslösen würde, solange die Funktion am oberen Rand des Bereichs deklariert ist.
javascript
coffeescript
jslint
function-declaration
Grace Shao
quelle
quelle
class
es.Antworten:
CoffeeScript verwendet Funktionsdeklarationen (auch als "benannte Funktionen" bezeichnet) an nur einer Stelle:
class
Definitionen. Zum Beispiel,class Foo
kompiliert zu
var Foo; Foo = (function() { function Foo() {} return Foo; })();
Der Grund, warum CoffeeScript laut FAQ keine Funktionsdeklarationen an anderer Stelle verwendet :
Kurz gesagt: Die unachtsame Verwendung von Funktionsdeklarationen kann zu Inkonsistenzen zwischen dem IE (vor 9) und anderen JS-Umgebungen führen, sodass CoffeeScript diese meidet.
quelle
var a = function a() {};
. B. ). Funktionsdeklarationen (z. B.function a() {}
) weisen keine derartigen browserübergreifenden Inkonsistenzen aufJa, du kannst:
hello() `function hello() {` console.log 'hello' dothings() `}`
Sie entkommen reinem JS über das Backtick `
Beachten Sie, dass Sie Ihren Funktionskörper nicht einrücken können.
Prost
quelle
function updateSettings() {
; do -> dothings ()}
, um Einrückungen zu ermöglichen. github.com/jashkenas/coffeescript/issues/…Eine Sache, die Sie bei CoffeeScript beachten sollten, ist, dass Sie jederzeit auf JavaScript zurückgreifen können. Während CoffeeScript benannte Funktionsdeklarationen nicht unterstützt, können Sie dazu jederzeit auf JavaScript zurückgreifen.
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; }`
Sie können auch eine große Fettfunktion in CoffeeScript schreiben und dann einfach den Backticks-Trick verwenden, damit JavaScript die andere Funktion aufruft:
# 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); }`
quelle
Nein, Sie können eine Funktion im Kaffeeskript nicht definieren und eine Funktionsdeklaration im Kaffeeskript generieren lassen
Auch wenn Sie nur schreiben
-> 123
Das generierte JS wird in Parens eingeschlossen, wodurch es zu einem Funktionsausdruck wird
(function() { return 123; });
Ich vermute, dass dies daran liegt, dass Funktionsdeklarationen an die Spitze des umschließenden Bereichs "gehisst" werden, was den logischen Fluss der Coffeescript-Quelle unterbrechen würde.
quelle
Während dies ein älterer Beitrag ist, wollte ich der Konversation für zukünftige Googler etwas hinzufügen.
OP ist insofern richtig, als wir keine Funktionen in reinem CoffeeScript deklarieren können (mit Ausnahme der Idee, Back-Ticks zu verwenden, um reines JS in der CoffeeScript-Datei zu umgehen).
Was wir aber tun können, ist, die Funktion an das Fenster zu binden und im Wesentlichen etwas zu erhalten, das wir aufrufen können, als wäre es eine benannte Funktion. Ich sage dies nicht ist eine benannte Funktion, ich bin ein Weg , um zu tun , was ich OP vorstellen will tatsächlich tun (nennen wir eine Funktion wie foo (param) irgendwo im Code) unter Verwendung von reinem Coffeescript .
Hier ist ein Beispiel für eine Funktion, die in Coffeescript an das Fenster angehängt ist:
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
Hierbei werden Google Places verwendet, um Adressinformationen zurückzugeben und ein Formular automatisch auszufüllen.
Wir haben also einen Teil in einer Rails-App, der auf eine Seite geladen wird. Dies bedeutet, dass das DOM bereits erstellt wurde. Wenn wir die obige Funktion beim ersten Laden der Seite aufrufen (bevor der Ajax-Aufruf den Teil rendert), sieht jQuery das Element $ ('# property_street_address_1') nicht (vertrau mir - es hat nicht funktioniert). t).
Daher müssen wir google.maps.places.Autocomplete () verzögern, bis das Element auf der Seite vorhanden ist.
Wir können dies über den Ajax-Rückruf bei erfolgreichem Laden des Teils tun:
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
Hier machen wir also im Wesentlichen dasselbe wie beim Aufrufen von foo ()
quelle
Warum? Weil Funktionsdeklaration böse ist. Schauen Sie sich diesen Code an
function a() { return 'a'; } console.log(a()); function a() { return 'b'; } console.log(a());
Was wird auf der Ausgabe sein?
Wenn wir die Funktionsdefinition verwenden
var a = function() { return 'a'; } console.log(a()); a = function() { return 'b'; } console.log(a());
Die Ausgabe ist:
quelle
Versuche dies:
defineFct = (name, fct)-> eval("var x = function #{name}() { return fct.call(this, arguments); }") return x
Jetzt wird Folgendes "true" ausgegeben:
foo = defineFct('foo', ()->'foo') console.log(foo() == foo.name)
Ich benutze das eigentlich nicht, aber manchmal wünschte ich mir, Kaffee-Funktionen hätten Namen für die Selbstbeobachtung.
quelle