Noto que en CoffeeScript, si defino una función usando:
a = (c) -> c=1
Solo puedo obtener la expresión de la función :
var a;
a = function(c) {
return c = 1;
};
Pero, personalmente, a menudo uso la declaración de función , por ejemplo:
function a(c) {
return c = 1;
}
Utilizo el primer formulario, pero me pregunto si hay alguna forma en CoffeeScript de generar una declaración de función. Si no existe tal manera, me gustaría saber por qué CoffeeScript evita hacer esto. No creo que JSLint grite un error para la declaración, siempre que la función se declare en la parte superior del alcance.
javascript
coffeescript
jslint
function-declaration
Grace Shao
fuente
fuente
class
es.Respuestas:
CoffeeScript usa declaraciones de funciones (también conocidas como "funciones con nombre") en un solo lugar:
class
definiciones. Por ejemplo,class Foo
compila a
var Foo; Foo = (function() { function Foo() {} return Foo; })();
La razón por la que CoffeeScript no usa declaraciones de funciones en otros lugares, según las preguntas frecuentes :
En resumen: el uso descuidado de las declaraciones de funciones puede generar inconsistencias entre IE (pre-9) y otros entornos JS, por lo que CoffeeScript las evita.
fuente
var a = function a() {};
). Las declaraciones de funciones (por ejemplofunction a() {}
) no tienen tales inconsistencias entre navegadoresSí tu puedes:
hello() `function hello() {` console.log 'hello' dothings() `}`
Escapas de JS puro a través de la comilla invertida `
Tenga en cuenta que no puede aplicar sangría al cuerpo de su función.
Salud
fuente
function updateSettings() {
; hacer -> dothings ()}
para permitir la sangría. github.com/jashkenas/coffeescript/issues/…Una cosa a tener en cuenta con CoffeeScript es que siempre puede volver a JavaScript. Si bien CoffeeScript no admite declaraciones de funciones con nombre, siempre puede volver a JavaScript para hacerlo.
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; }`
También puede escribir una función grande en CoffeeScript y luego usar el truco de las comillas invertidas para que JavaScript llame a la otra función:
# 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); }`
fuente
No, no puede definir una función en el script de café y hacer que genere una declaración de función en el script de café
Incluso si solo escribes
-> 123
el JS generado se envolverá en parens, convirtiéndolo en una expresión de función
(function() { return 123; });
Supongo que esto se debe a que las declaraciones de funciones se "elevan" a la parte superior del alcance adjunto, lo que rompería el flujo lógico de la fuente coffeescript.
fuente
Si bien esta es una publicación anterior, quería agregar algo a la conversación para futuros empleados de Google.
OP tiene razón en que no podemos declarar funciones en CoffeeScript puro (excluyendo la idea de usar ticks inversos para escapar JS puro dentro del archivo CoffeeScript).
Pero lo que podemos hacer es vincular la función a la ventana y esencialmente terminar con algo que podemos llamar como si fuera una función con nombre. No estoy diciendo que esto sea una función con nombre, estoy proporcionando una forma de hacer lo que imagino que OP quiere hacer (llamar a una función como foo (param) en algún lugar del código) usando CoffeeScript puro.
Aquí hay un ejemplo de una función adjunta a la ventana 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
Esto está utilizando Google Places para devolver la información de la dirección para completar automáticamente un formulario.
Así que tenemos un parcial en una aplicación Rails que se está cargando en una página. Esto significa que el DOM ya está creado, y si llamamos a la función anterior en la carga de la página inicial (antes de que la llamada ajax muestre el parcial), jQuery no verá el elemento $ ('# property_street_address_1') (confía en mí, no lo hizo) t).
Por lo tanto, debemos retrasar google.maps.places.Autocomplete () hasta que el elemento esté presente en la página.
Podemos hacer esto a través de la devolución de llamada Ajax en la carga exitosa del parcial:
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
Entonces, aquí, esencialmente, estamos haciendo lo mismo que llamar a foo ()
fuente
¿Por qué? Porque la declaración de función es mala. Mira este código
function a() { return 'a'; } console.log(a()); function a() { return 'b'; } console.log(a());
¿Qué habrá en la salida?
Si usamos la definición de función
var a = function() { return 'a'; } console.log(a()); a = function() { return 'b'; } console.log(a());
la salida es:
fuente
Prueba esto:
defineFct = (name, fct)-> eval("var x = function #{name}() { return fct.call(this, arguments); }") return x
Ahora lo siguiente imprimirá "verdadero":
foo = defineFct('foo', ()->'foo') console.log(foo() == foo.name)
En realidad, no uso esto, pero a veces desearía que las funciones de café tuvieran nombres para la introspección.
fuente