Coffeescript is actually a very flexible language because it can be translated into JavaScript in a one-to-one manner. There are more than one way to bring it into the project. Here, I will first introduce the node project Coffeescript Way to make a summary, and compare the pros and cons of each way.
Run a pure Coffeescript project directly using the coffee Directive
generally mention coffeescript, and naturally think of him as the little brother of JavaScript, Always out of JS shadow. You can actually think of it as a separate language. We all know that on the node platform after the global installation of the Coffee-script package, you can go through the coffee instructions into the Coffeescript interface, call it REPL also line. If your project is entirely written in coffee, it's easy, just use the coffee directive on your entry script, such as "App.coffee", and then execute:
Coffee app.coffee
Note , the extension coffee here cannot be omitted.
This should be said to be the most "official" way to use Coffeescript. Simple, Direct! Moreover, once you use a coffee file as the entry point for the project, the entire project is compatible with both coffee and JS. You can arbitrarily require JS or coffee files and modules in the project, and can even require coffee files in the JS files in the project. And when you refer to either coffee or JS files, you do not need to extend the name, as long as the previous part of the name does not conflict. The biggest problem with
in this way is that if it is a module, it can only be used for coffee projects; If he is an application, the running environment must have Coffee-script installed. After all, Coffeescript is still a small language, it as a module when the loss of JS users is really a pity.
Another possible disadvantage is performance, after all, node inside only JS engine, coffee code needs to compile for JS before running, this process is to consume a little time, although coffee to JS compiler speed is actually very fast. However, this should not be a big problem, in general, require are written in the top of the file, that is, the application in the start-up when the require of the files are require, require when the coffee was compiled into JS into the JS engine, So the time that the compilation consumes is concentrated in the application starts, the runtime hardly encounters the require new coffee situation. The most common use scenario for node is the Web server, which is even more problematic.
Referencing Coffeescript in a JavaScript project
Coffee-script in NPM can be installed either globally or as a module of the project. What's the point of Coffee-script as a module of the project? In fact, you add a coffeescript compiler to your project, and the project can compile coffee files at run time.
You must want to refer to coffee files as casually as in the first way. No problem, just register. If your project entry file is App.js, then just add this to the front of the file:
Require (' coffee-script/register ');
Then you can require coffee files in the project.
This approach is essentially the same as the first way, except that Coffee-script is not installed in the global, so your module can be independent, as the application does not need the environment to install good coffee-script.
Shortcomings, I think the biggest problem is easy to make code a bit messy, a while JS, a while coffee, of course, the first way may also be so, but all with coffee started inside should not write JS it ... In a word, I think a project or the language unified better (unfortunately I mainly in this way, in a JS has been written in the general structure of the project, I would like to use coffee swollen mody do ... )
The performance problem is the same as the first way, not much.
the Orthodox Way--compiling
Once the compilation, I feel back to the serious of the C or Java era. Indeed, as a compiled language, compiling and then running is the right path. c There are Gcc,java Javac,cofee have coffee-c.
It is easy to compile a cofee file, such as to edit the App.coffee file, which is executed in the current directory of the file:
Coffee-c App.coffee
A file named App.js appears in the current directory. This instruction can also be applied to the directory, such as you put all the coffee source files in the project in the SRC directory, then execute:
Coffee-c SRC
All coffee source files in the SRC directory and its various subdirectories are compiled into a JS file and placed in the same directory as the source file.
However, for large projects, it is not good to put the source file and the compiled result file together. It's OK to specify an output directory:
COFFEE-C-o outputs src
The parameter order of this instruction is a bit strange. This is defined in the help of coffee:
coffee [Options] path/to/script.coffee--[args]
Note that all options are between the coffee and the file path. The final args is the parameter to pass when the target file is executed as a script. That means that all the options are placed between the coffee and the filename. And-c This option is separate, does not have its own parameters, it only means that the instructions to the last side of the file provided to compile, so write this is also the line:
Coffee-o outputs-c src
If you want to add an option so that the result of the compilation is not surrounded by the execution function body, it is:
Coffee-o Outputs-c-B src
If you want to compile all the source files into a target file named Out.js, you are:
Coffee-o outputs-c-j out SRC
It's annoying to execute instructions every time a pity Dorado code. Coffee directive has an option-----------------
Coffee-o outputs-c-W SRC
For large projects, it's best to make sure that the compilation is done in advance, so that all developers need only one instruction to fix all the things that are compiled, and this needs to be built automatically.
Offee provides an automated build tool, cake, just like make in C world. But as the official web site says, cake is a very simple build system. In fact, the function of cake is to execute a script called Cakefile, and the Cakefile script is written in Coffeescript. This script provides only a very limited set of built-in functions, such as a task, to declare a command and its corresponding description and execution function. The other is to write a pure node project, want to compile either use node's FS module output coffee module compiled strings, or use child_process module to execute shell directives. In fact, the goal of cake construction does not have to be coffee, because it actually executes a node script that handles anything that is automated.
There are also a number of better third-party automation building tools can also be completed coffee automatic compilation, such as the famous grunt, as well as the domestic fekit.
This orthodox way of compiling may seem the most reliable, and should be loved by older programmers. It allows the team to form a fixed development model. In addition, the compiled project becomes a pure JS project, whether as an application directly or as a module by other project references do not need additional dependency. And there is no need for compilation at run time, and there is no performance problem with compilation at all.
The disadvantage is that it is too troublesome. If you are going to do a not too big project, Cakefile or configure Grunt to spend half a day, not very worthwhile.
Using Coffeescript and Node for functional JavaScript programming
Functional scripting controls the complexity of WEB applications
Coffeescript has a reputation for filling in the imperfections of JavaScript, but it has other advantages that are worth exploring. In this article, Andrew Glover will show you how Coffeescript's cleaner syntax makes it easier to take advantage of functional structures in JavaScript libraries, especially for server-side programming in Node.js. The authors end with a series of brief demos showing how to use JavaScript's utility library underscore.js to handle collections in Coffeescript and Node.
Coffeescript is a relatively new language, providing developers with a promising solution that no longer has JavaScript defects. With Coffeescript, developers can use a lightweight, intuitive language to complete coding, a language that is like a hybrid of Ruby and Python. For browser-compatible WEB applications, Coffeescript will compile to JavaScript, and it will work seamlessly with Node.js for server-side applications. The core of this article is the use of the third benefit of Coffeescript, which is the function of processing JavaScript functions. Coffeescript has a neat, modern syntax that frees up the functional programming world lurking in the JavaScript library.
Functional programming in the mainstream programming language
Although none of the major programming languages (such as Java™, C + +, and C #) are explicitly used as functional programming languages, additional libraries and frameworks in these languages implement various levels of functional programming. More importantly, languages such as Clojure, F #, and Erlang are becoming more mainstream because functional programming produces fewer bugs and increases the productivity of complex applications.
Like JavaScript, functional programming is also very useful, but it is also very unpopular for some time. JavaScript was originally considered a toy language, while functional programming was known for its high complexity. But as demand for highly concurrent applications increases, there is an urgent need to find an alternative way to replace the existing programming style. Functional programming has proven to be an excellent tool for organizing the complexities inherent in some types of applications without the needless complexity of hearsay.
In this article, we'll explore how to do functional scripting in Coffeescript and Node using a JavaScript library called underscore. Combining these three technologies will create a powerful technology system that enables you to use JavaScript to develop server-side and browser-based applications that use functional programming.
setting up Coffeescript and Node
If Node.js is already installed in your development environment, you can install Coffeescript directly using its Package Manager (NPM). The following command tells NPM to install the package globally:
$> NPM install-g Coffee-script
When using Coffeescript, most of your time will be spent writing programs, saving them as. coffee files, and then compiling the results into JavaScript. Coffeescript's syntax is so close to JavaScript syntax that most developers can easily get started; for example, the Coffeescript script in Listing 1 is very similar to JavaScript, except that it's not common in JavaScript. Disorderly parentheses and semicolons:
Listing 1. Typical coffeescript.
$> coffee-bpe "Console.log ' Hello Coffee '" console.log (' Hello Coffee ');
The coffee command is the shortest way to perform certain administrative tasks. It can compile coffeescript files into JavaScript, run coffeescript files, or even as an interactive environment or REPL (similar to Ruby's IRB).
Next, I save my script to a file:
Console.log "Hello coffee"
I then compile (or convert) this file to JavaScript:
$> coffee-c Hello.coffee
Results A file named Hello.js was obtained. Because the resulting JavaScript script is equally valid for node, I can run it directly in my node environment:
Listing 2. Running JavaScript in Node
$> node Hello.js Hello coffee!
In addition, I can use the coffee command to run the original. coffee file, as shown in Listing 3:
Listing 3. Running Coffeescript in Node
$> Coffee Hello.coffee Hello coffee!
Watch the Monitor tool-WATCHR
The open source community has produced a large number of handy file monitor utilities to complete tasks such as running tests, compiling code, and so on. These tools usually work on the command line and are extremely lightweight tools. We will configure the Monitor tool to monitor all the. coffee files in our development environment and compile them as. js files at save time.
The utility that I like to use in achieving this goal is WATCHR, a Ruby library. In order to use WATCHR, you need to install Ruby and RubyGems in your development environment. After the installation is complete, you can run the following command to install WATCHR as a global Ruby library (including the appropriate utilities):
$> Gem Install WATCHR
In WATCHR, you use regular expressions to define the files that you want to monitor, and the actions that should be performed on them. The following command configures WATCHR to compile all. Coffee files found in the SRC directory:
Watch (' Src\/.*\.coffee ') {|match| system "coffee--compile--output js/src/"}
Please note that the coffee command in this example places the resulting. js file in a JS directory.
I can trigger this action in a terminal window, for example:
$> WATCHR PROJECT.WATCHR
Now, as soon as I make changes to any. coffee file in the SRC directory, WATCHR ensures that a new. js file is created and placed in my JS directory.
Coffeescript Overview
Coffeescript introduces a variety of highly valuable features, making it easier to use than JavaScript. Coffeescript largely eliminates the need to use curly braces, semicolons, and VAR keywords, function keywords. In fact, one of my favorite Coffeescript features is its function definition, as shown in Listing 4:
Listing 4. The Coffeescript function is very simple!
Capitalize = (word)->
Word.charat (0). toUpperCase () + word.slice 1
Console.log capitalize "Andy"//prints Andy
Here, I declare a simple function in Coffeescript to capitalize the first letter of a word. In Coffeescript, the syntax for a function definition is immediately after an arrow. The body part is also separated by a space, so coffeescript does not have curly braces. Also note that parentheses are not used here. Coffeescript's Word.slice 1 will be compiled into JavaScript's Word.slice (1). Again, notice that the subject part of the function is also separated by a space: all the code in the function definition line is indented. The console.log representation of the lower-indented method is fully defined. (these two features of Coffeescript are drawn from Ruby and Python, respectively.) )
You might want to know what the corresponding JavaScript function is, listing 5 gives the corresponding JavaScript code:
Listing 5. Even JavaScript's single line of code is very complicated.
var capitalize = function (word) {
Return Word.charat (0). toUpperCase () + word.slice (1);
};
Console.log (Capitalize ("Andy"));
variable
Coffeescript can automatically add JavaScript-style var before any variables you define. Therefore, when writing code in Coffeescript, you do not need to remember var. (the var keyword in JavaScript is optional.) Without this keyword, your variable will become a global variable, which in most cases would be an unreasonable practice. )
Coffeescript also allows you to define default values for parameters, as shown in Listing 6:
Listing 6. Default parameter Value!
Greeting = (recipient = "World")->
"Hello #{recipient}"
Console.log greeting "Andy"//prints Hello Andy
Console.log greeting ()//prints Hello World
Listing 7 shows how the corresponding JavaScript script handles this default parameter value:
Listing 7. Clutter of JavaScript
var greeting;
Greeting = function (recipient) {
if (recipient = = null) recipient = "World";
Return "Hello" + recipient;
};
Conditions
Coffeescript can process conditions by introducing keywords such as and, or, and not, as shown in Listing 8:
Listing 8. Coffeescript conditions
Capitalize = (word)->
If Word? and typeof (Word) is ' string '
Word.charat (0). toUpperCase () + word.slice 1
Else
Word
Console.log capitalize "Andy"//prints Andy
Console.log capitalize null//prints NULL
Console.log Capitalize 2//prints 2
Console.log capitalize "Betty"//prints Betty
In Listing 8, I used the? The operator tests whether the condition exists or not. Before attempting to capitalize the first letter of a word, the script ensures that the argument word is not null and that it is a string type. The great thing about Coffeescript is that it allows you to use is to replace = =.
class definitions for functional programming
JavaScript does not directly support classes; It is a prototype-oriented language. For those who are still immersed in object-oriented programming, this can be confusing-we want our own class! To meet this requirement, COFFEESCRIPT provides a class syntax that, when compiled into standard JavaScript, gets a series of functions defined within a function.
In Listing 9, I used the class keyword to define a class named message:
Listing 9. Coffeescript does support classes
Class message
Constructor: (@to, @from, @message)->
Asjson:->
Json.stringify ({to: @to, from: @from, message: @message})
Mess = new Message "Andy", "Joe", "party!"
Console.log Mess.asjson ()
In Listing 9, I defined a constructor using the constructor keyword. Then I entered a name, followed by a function, and I defined a method in this way (Asjson).
Coffeescript and Node
The Coffeescript script will be compiled as a JavaScript script, so Coffeescript is the ideal choice for programming in node and is also helpful in simplifying node's already very neat code. Coffeescript is extremely adept at simplifying the multiple callbacks of Node, which can be seen by a simple code comparison. In Listing 10, I defined a simple Node Web application using the pure JavaScript method:
Listing 10. A node.js Web application written using JavaScript
var express = require (' Express ');
var app = Express.createserver (Express.logger ());
App.put ('/', function (req, res) {
Res.send (json.stringify ({status: "Success"}));
});
var port = Process.env.PORT | | 3000;
App.listen (port, function () {
Console.log ("Listening on" + port);
});
Rewrite the same Web application in Coffeescript to eliminate the complex syntax of the Node callback, as shown in Listing 11:
Listing 11. Coffeescript simplifies the Node.js
Express = Require ' express '
App = Express.createserver Express.logger ()
App.put '/', (req, res)->
Res.send json.stringify {status: "Success"}
Port = Process.env.PORT or 3000
App.listen Port,->
Console.log "listening on" + Port
In Listing 11, I added an OR operator to replace JavaScript | |. In addition, I find it easier to use arrows to represent anonymous functions in app.listen than to type function () directly.
Coffeescript is like everyday language
Now, you may well have realized that coffeescript tends to use abstract symbols in everyday English representations. In Coffeescript, we are not typing!==, but we can use more intuitive isnt, as well as = = =.
If you perform coffee-c on this file, you will see that Coffeescript generates a JavaScript script that is almost identical to the one shown in Listing 10. 100% valid JavaScript scripts in Coffeescript can be used in conjunction with any JavaScript library.
Implementing functional collections through underscore
As a functional utility for JavaScript programming, Underscore.js is a library of functions that can simplify JavaScript development. In addition to other features, underscore provides a rich set of collection-oriented functions that are ideal for handling special tasks.
For example, suppose you need to find all the odd numbers in a set of digits that contain numbers from 0 to 10 (excluding 10). While you can solve this problem, using coffeescript and underscore together can save you a lot of typing time and perhaps reduce bugs. In Listing 12, I provide the basic algorithm, and underscore provides the aggregate function, which is the filter in this example:
Listing 12. The filter function of underscore
_ = Require ' underscore '
Numbers = _.range (10)
Odds = _ (Numbers). filter (x)->
X% 2 isnt 0
Console.log Odds
First, because _ (that is, underscore) is a valid variable name, I set it to refer to the underscore library. Next, I append an anonymous function to the test-odd filter function. Note that I use the coffeescript isnt keyword, not the JavaScript!== keyword. I then used the range function to specify that I wanted to sort the number 0 through 9, and I also specified a step count (that is, 2 count) for my range, starting with any number.
The filter function returns an array, which is a filtered version of the array passed to the function, in this case the returned array is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. So the code that runs listing 12 will get [1, 3, 5, 7, 9].
The map function is another function that I most often apply to a collection in JavaScript, as shown in Listing 13:
Listing 13. The map function of underscore
OneUp = _ (Numbers). Map (x)->
X + 1
Console.log OneUp
Here, the output should be [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. Typically, underscore increments the values in the numbers range by 1, so I don't have to traverse each integer manually.
If you need to test multiple aspects of a collection, underscore can help you simplify everything! Just create a function similar to the one shown in Listing 14, which is used to test even numbers:
Listing 14. The even function of underscore
even = (x)->
X 2 is 0
Console.log _ (Numbers). All (even)
Console.log _ (Numbers). any (even)
Once you have defined the even function, you can easily connect it to the underscore function, such as all and any. In this case, all applies my even function to every value in the numbers range. It then returns a Boolean value indicating whether all values are even (false). Similarly, if any value is even (true), the Any function returns a Boolean value of true.
Use underscore to accomplish more tasks
This paper can simply introduce some general situation of underscore. Other features of underscore include functional bindings, JavaScript template authoring, and testing for depth equality. (See the Resources section.) )
What if you don't need to apply any of these functions to a collection of values, but you need to do something else? No problem at all! Take advantage of the underscore each function. Each function acts as an easy-to-use iterator (that is, it handles the loop logic behind the scene, passing in the specified function each iteration). If you have used Ruby or Groovy, you should be familiar with this function.
Listing 15. Each function of the underscore
_.each numbers, (x)->
Console.log (x)
In Listing 15, the each function gets a collection (my numbers range) and a function that needs to be applied to the values in an iterative group. In this case, I use each to output the value of the current iteration to the console. For me, what needs to be done is as simple as saving the data to the data and returning the results to the user.
Concluding remarks
Coffeescript is refreshing to JavaScript programming and simplifies JavaScript programming, so any user can easily get started, especially if they are familiar with Ruby or Python. In this article, I showed how coffeescript can make JavaScript-style code easier to read by drawing on these languages, while also significantly speeding up the process of writing. As I demonstrated, combining Coffeescript, Node, and underscore gets a very lightweight, interesting development stack (development stack) that works with basic functional programming scenarios. After a period of practice, you will be able to base your knowledge in this article on more complex business applications that rely on dynamic Web and mobile interaction.