javascript coffeescript jslint function-declaration

coffeescript vs javascript



DeclaraciĆ³n de funciĆ³n en CoffeeScript (7)

¿Por qué? Porque la declaración de la función es malvada. Mira este código

function a() { return ''a''; } console.log(a()); function a() { return ''b''; } console.log(a());

¿Qué estará en la salida?

b b

Si usamos la definición de la función

var a = function() { return ''a''; } console.log(a()); a = function() { return ''b''; } console.log(a());

la salida es:

a b

Noté 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 declaraciones de funciones , por ejemplo:

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

Utilizo el primer formulario, pero me pregunto si hay una manera en CoffeeScript de generar una declaración de función. Si no hay tal forma, me gustaría saber por qué CoffeeScript evita hacer esto. No creo que JSLint gritara un error para la declaración, siempre y cuando la función se declare en la parte superior del alcance.


CoffeeScript utiliza declaraciones de funciones (también conocidas como "funciones nombradas") en un solo lugar: definiciones de class . Por ejemplo,

class Foo

compila a

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

La razón por la que CoffeeScript no utiliza declaraciones de funciones en otro lugar, de acuerdo con las FAQ :

Culpar a Microsoft por este. Originalmente cada función que podía tener un nombre razonable recuperado se le dio una, pero las versiones IE 8 y anteriores tienen problemas de alcance donde la función nombrada se trata como una declaración y una expresión. Vea this para más información.

En resumen: el uso descuidado de las declaraciones de funciones puede provocar inconsistencias entre IE (pre-9) y otros entornos JS, por lo que CoffeeScript las evita.


No, no puedes definir una función en Coffee Script y hacer que genere una declaración de función en Coffee Script

Incluso si solo escribes

-> 123

el JS generado estará envuelto en parens, convirtiéndolo así en una expresión de función

(function() { return 123; });

Mi suposición es que esto se debe a que las declaraciones de funciones se "alzan" al principio del alcance adjunto, lo que rompería el flujo lógico de la fuente del coffeescript.


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)

Realmente no uso esto, pero a veces deseo que las funciones de café tengan nombres para la introspección.


Sí tu puedes:

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

Te escapas JS puro a través del backtick `

Tenga en cuenta que no puede aplicar sangría en su cuerpo de función.

Aclamaciones


Si bien esta es una publicación anterior, quería agregar algo a la conversación para futuros Googlers.

OP es correcto en que no podemos declarar funciones en CoffeeScript puro (excluyendo la idea de usar back-ticks para escapar de 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 nombrada. No estoy diciendo que se trata de una función con nombre, estoy proporcionando una forma de hacer lo que imagino que OP quiere hacer realmente (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á usando Google Places para devolver información de la dirección para rellenar automáticamente un formulario.

Entonces, tenemos un parcial en una aplicación de 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 represente el parcial), jQuery no verá el elemento $ (''# property_street_address_1'') (confía en mí, no lo hizo t).

Entonces, 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 de 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

Aquí, básicamente, estamos haciendo lo mismo que llamar a foo ()


Una cosa a tener en cuenta con CoffeeScript es que siempre puedes volver a JavaScript. Si bien CoffeeScript no es compatible con las declaraciones de función nombradas, siempre puede volver a utilizar 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 teclas de retroceso 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); }`