How to Use Functions and Arguments in CoffeeScript
- Function Basics
- Arguments
- Default Arguments
- Splats...
- Wrapping Up
I wanted to give you an example of what JavaScript would look like if we were not able to use or write functions, but I was unable to. Even the simplest example of taking a string and making it lowercase requires the use of functions in JavaScript.
Because I can’t show you an example devoid of functions, I’ll show you an example of some CoffeeScript code that could use the help of a function or two, so you can see how important functions are to helping you keep your code manageable.
Example: (source: no_functions_example.coffee)
tax_rate = 0.0625 val = 100 console.log "What is the total of $#{val} worth of shopping?" tax = val * tax_rate total = val + tax console.log "The total is #{total}" val = 200 console.log "What is the total of $#{val} worth of shopping?" tax = val * tax_rate total = val + tax console.log "The total is #{total}"
Example: (source: no_functions_example.js)
(function() { var tax, tax_rate, total, val; tax_rate = 0.0625; val = 100; console.log("What is the total of $" + val + " worth of shopping?"); tax = val * tax_rate; total = val + tax; console.log("The total is " + total); val = 200; console.log("What is the total of $" + val + " worth of shopping?"); tax = val * tax_rate; total = val + tax; console.log("The total is " + total); }).call(this);
Output: (source: no_functions_example.coffee)
What is the total of $100 worth of shopping? The total is 106.25 What is the total of $200 worth of shopping? The total is 212.5
In our example, we are calculating the total value of goods purchased in-state with certain sales tax. Apart from the banality of the example, you can see that we are repeating our code to calculate the total value with tax several times.
Let’s refactor our code a bit, add some functions, and try to clean it up.
Example: (source: with_functions_example.coffee)
default_tax_rate = 0.0625 calculateTotal = (sub_total, rate = default_tax_rate) -> tax = sub_total * rate sub_total + tax val = 100 console.log "What is the total of $#{val} worth of shopping?" console.log "The total is #{calculateTotal(val)}" val = 200 console.log "What is the total of $#{val} worth of shopping?" console.log "The total is #{calculateTotal(val)}"
Example: (source: with_functions_example.js)
(function() { var calculateTotal, default_tax_rate, val; default_tax_rate = 0.0625; calculateTotal = function(sub_total, rate) { var tax; if (rate == null) rate = default_tax_rate; tax = sub_total * rate; return sub_total + tax; }; val = 100; console.log("What is the total of $" + val + " worth of shopping?"); console.log("The total is " + (calculateTotal(val))); val = 200; console.log("What is the total of $" + val + " worth of shopping?"); console.log("The total is " + (calculateTotal(val))); }).call(this);
Output: (source: with_functions_example.coffee)
What is the total of $100 worth of shopping? The total is 106.25 What is the total of $200 worth of shopping? The total is 212.5
You probably don’t understand everything we just did there, but don’t worry, that’s what this chapter is for. However, even without knowing the specifics of how functions are defined, and work, in CoffeeScript, you can see how much cleaner our code is between the two examples. In the refactored code, we are even able to pass in a different tax rate, should we need to. This also helps us keep our code DRY 1: Don’t Repeat Yourself. Not repeating your code makes for an easier-to-manage code base with, hopefully, fewer bugs.
Function Basics
We’ll start with the very basics on how to define a function in CoffeeScript. The anatomy of a very simple function looks like this:
Example: (source: simple_function.coffee)
myFunction = ()-> console.log "do some work here" myFunction()
Example: (source: simple_function.js)
(function() { var myFunction; myFunction = function() { return console.log("do some work here"); }; myFunction(); }).call(this);
In that example we gave the function a name, myFunction, and a code block to go with it. The body of the function is the code that is indented below the ->, following the significant whitespace rules we learned about in Chapter 2, “The Basics.”
The function does not accept any arguments. We know that by the empty parentheses prior to the ->. When calling a function in CoffeeScript that has no arguments, we are required to use parentheses, myFunction().
Because our function has no arguments, we can drop the parentheses entirely when defining it, like so:
Example: (source: simple_function_no_parens.coffee)
myFunction = -> console.log "do some work here" myFunction()
Example: (source: simple_function_no_parens.js)
(function() { var myFunction; myFunction = function() { return console.log("do some work here"); }; myFunction(); }).call(this);
There is one more way we can write this simple function. Because the body of our function is on only one line, we can collapse the whole function definition to one, like this:
Example: (source: simple_function_one_line.coffee)
myFunction = -> console.log "do some work here" myFunction()
Example: (source: simple_function_one_line.js)
(function() { var myFunction; myFunction = function() { return console.log("do some work here"); }; myFunction(); }).call(this);
All three of the previous code examples produce the same JavaScript and are called in the same way.