mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Handle ids within the template, not in the Cakefile; remove marked’s auto-generated and conflicting ids
This commit is contained in:
parent
4aa0130a92
commit
ff1725b367
3 changed files with 134 additions and 171 deletions
3
Cakefile
3
Cakefile
|
@ -180,6 +180,8 @@ task 'doc:site', 'watch and continually rebuild the documentation for the websit
|
|||
htmlFor = ->
|
||||
marked = require 'marked'
|
||||
markdownRenderer = new marked.Renderer()
|
||||
markdownRenderer.heading = (text, level) ->
|
||||
"<h#{level}>#{text}</h#{level}>" # Don’t let marked add an id
|
||||
markdownRenderer.code = (code) ->
|
||||
if code.indexOf('codeFor(') is 0 or code.indexOf('releaseHeader(') is 0
|
||||
"<%= #{code} %>"
|
||||
|
@ -195,7 +197,6 @@ task 'doc:site', 'watch and continually rebuild the documentation for the websit
|
|||
html = _.template(html)
|
||||
codeFor: codeFor()
|
||||
releaseHeader: releaseHeader
|
||||
"<span class=\"bookmark\" id=\"#{if bookmark? then bookmark else file.replace(/_/g, '-')}\"></span>\n\n#{html}"
|
||||
|
||||
include = ->
|
||||
(file) ->
|
||||
|
|
|
@ -599,20 +599,16 @@ pre .xml .cdata {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<span class="bookmark" id="top"></span>
|
||||
|
||||
<p><strong>CoffeeScript is a little language that compiles into JavaScript.</strong> Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.</p>
|
||||
<div id="top" class="container">
|
||||
<span class="bookmark" id="overview"></span>
|
||||
<p><strong>CoffeeScript is a little language that compiles into JavaScript.</strong> Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.</p>
|
||||
<p>The golden rule of CoffeeScript is: <em>“It’s just JavaScript”</em>. The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.</p>
|
||||
<p>The CoffeeScript compiler goes to great lengths to generate output JavaScript that runs in every JavaScript runtime, but there are exceptions. Use <a href="#generator-functions">generator functions</a>, <a href="#generator-iteration"><code>for…from</code></a>, or <a href="#tagged-template-literals">tagged template literals</a> only if you know that your <a href="http://kangax.github.io/compat-table/es6/">target runtimes can support them</a>. If you use <a href="#modules">modules</a>, you will need to <a href="#modules-note">use an additional tool to resolve them</a>.</p>
|
||||
<p><strong>Latest Version:</strong> <a href="http://github.com/jashkenas/coffeescript/tarball/1.12.1">1.12.1</a></p>
|
||||
<blockquote>
|
||||
<pre><code>npm install -g coffee-script</code></pre></blockquote>
|
||||
|
||||
<span class="bookmark" id="overview"></span>
|
||||
|
||||
<h2 id="overview">Overview</h2>
|
||||
<p><em>CoffeeScript on the left, compiled JavaScript output on the right.</em></p>
|
||||
<h2>Overview</h2><p><em>CoffeeScript on the left, compiled JavaScript output on the right.</em></p>
|
||||
<div class='code'><pre><code><span class="comment"># Assignment:</span>
|
||||
number = <span class="number">42</span>
|
||||
opposite = <span class="literal">true</span>
|
||||
|
@ -731,9 +727,7 @@ cubes = (function() {
|
|||
})();
|
||||
;alert(cubes);">run: cubes</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="installation"></span>
|
||||
|
||||
<h2 id="installation">Installation</h2>
|
||||
<p>The CoffeeScript compiler is itself <a href="v1/annotated-source/grammar.html">written in CoffeeScript</a>, using the <a href="http://jison.org">Jison parser generator</a>. The command-line version of <code>coffee</code> is available as a <a href="http://nodejs.org/">Node.js</a> utility. The <a href="v1/browser-compiler/coffee-script.js">core compiler</a> however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see “Try CoffeeScript”, above).</p>
|
||||
<h2>Installation</h2><p>The CoffeeScript compiler is itself <a href="v1/annotated-source/grammar.html">written in CoffeeScript</a>, using the <a href="http://jison.org">Jison parser generator</a>. The command-line version of <code>coffee</code> is available as a <a href="http://nodejs.org/">Node.js</a> utility. The <a href="v1/browser-compiler/coffee-script.js">core compiler</a> however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see “Try CoffeeScript”, above).</p>
|
||||
<p>To install, first make sure you have a working copy of the latest stable version of <a href="http://nodejs.org/">Node.js</a>. You can then install CoffeeScript globally with <a href="http://npmjs.org">npm</a>:</p>
|
||||
<blockquote>
|
||||
<pre><code>npm install -g coffee-script</code></pre></blockquote>
|
||||
|
@ -748,9 +742,7 @@ cubes = (function() {
|
|||
<pre><code>sudo bin/cake install</code></pre></blockquote>
|
||||
|
||||
<span class="bookmark" id="usage"></span>
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
<p>Once installed, you should have access to the <code>coffee</code> command, which can execute scripts, compile <code>.coffee</code> files into <code>.js</code>, and provide an interactive REPL. The <code>coffee</code> command takes the following options:</p>
|
||||
<h2>Usage</h2><p>Once installed, you should have access to the <code>coffee</code> command, which can execute scripts, compile <code>.coffee</code> files into <code>.js</code>, and provide an interactive REPL. The <code>coffee</code> command takes the following options:</p>
|
||||
<table>
|
||||
|
||||
<tbody>
|
||||
|
@ -910,8 +902,7 @@ cubes = (function() {
|
|||
|
||||
</table>
|
||||
|
||||
<h3 id="examples-">Examples:</h3>
|
||||
<ul>
|
||||
<h3>Examples:</h3><ul>
|
||||
<li>Compile a directory tree of <code>.coffee</code> files in <code>src</code> into a parallel tree of <code>.js</code> files in <code>lib</code>:<br>
|
||||
<code>coffee --compile --output lib/ src/</code></li>
|
||||
<li>Watch a file for changes, and recompile it every time the file is saved:<br>
|
||||
|
@ -927,25 +918,19 @@ cubes = (function() {
|
|||
</ul>
|
||||
|
||||
<span class="bookmark" id="literate"></span>
|
||||
|
||||
<h2 id="literate-coffeescript">Literate CoffeeScript</h2>
|
||||
<p>Besides being used as an ordinary programming language, CoffeeScript may also be written in “literate” mode. If you name your file with a <code>.litcoffee</code> extension, you can write it as a Markdown document — a document that also happens to be executable CoffeeScript code. The compiler will treat any indented blocks (Markdown’s way of indicating source code) as code, and ignore the rest as comments.</p>
|
||||
<h2>Literate CoffeeScript</h2><p>Besides being used as an ordinary programming language, CoffeeScript may also be written in “literate” mode. If you name your file with a <code>.litcoffee</code> extension, you can write it as a Markdown document — a document that also happens to be executable CoffeeScript code. The compiler will treat any indented blocks (Markdown’s way of indicating source code) as code, and ignore the rest as comments.</p>
|
||||
<p>Just for kicks, a little bit of the compiler is currently implemented in this fashion: See it <a href="https://gist.github.com/jashkenas/3fc3c1a8b1009c00d9df">as a document</a>, <a href="https://raw.github.com/jashkenas/coffeescript/master/src/scope.litcoffee">raw</a>, and <a href="http://cl.ly/LxEu">properly highlighted in a text editor</a>.</p>
|
||||
<p>I’m fairly excited about this direction for the language, and am looking forward to writing (and more importantly, reading) more programs in this style. More information about Literate CoffeeScript, including an <a href="https://github.com/jashkenas/journo">example program</a>, are <a href="http://ashkenas.com/literate-coffeescript">available in this blog post</a>.</p>
|
||||
|
||||
<span class="bookmark" id="language"></span>
|
||||
|
||||
<h2 id="language-reference">Language Reference</h2>
|
||||
<p><em>This reference is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right.</em></p>
|
||||
<h2>Language Reference</h2><p><em>This reference is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right.</em></p>
|
||||
<p><em>Many of the examples can be run (where it makes sense) by pressing the <strong>run</strong> button on the right, and can be loaded into the “Try CoffeeScript” console by pressing the <strong>load</strong> button on the left.</em></p>
|
||||
<p>First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons <code>;</code> to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces <code>{ }</code> to surround blocks of code in <a href="#literals">functions</a>, <a href="#conditionals">if-statements</a>, <a href="#switch">switch</a>, and <a href="#try">try/catch</a>, use indentation.</p>
|
||||
<p>You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.<br>
|
||||
<code>console.log sys.inspect object</code> → <code>console.log(sys.inspect(object));</code></p>
|
||||
|
||||
<span class="bookmark" id="literals"></span>
|
||||
|
||||
<h2 id="functions">Functions</h2>
|
||||
<p>Functions are defined by an optional list of parameters in parentheses, an arrow, and the function body. The empty function looks like this: <code>-></code></p>
|
||||
<span class="bookmark" id="literals"></span>
|
||||
<h2>Functions</h2><p>Functions are defined by an optional list of parameters in parentheses, an arrow, and the function body. The empty function looks like this: <code>-></code></p>
|
||||
<div class='code'><pre><code><span class="function"><span class="title">square</span> = <span class="params">(x)</span> -></span> x * x
|
||||
<span class="function"><span class="title">cube</span> = <span class="params">(x)</span> -></span> square(x) * x
|
||||
</code></pre><pre><code><span class="keyword">var</span> cube, square;
|
||||
|
@ -986,10 +971,8 @@ fill = function(container, liquid) {
|
|||
return "Filling the " + container + " with " + liquid + "...";
|
||||
};
|
||||
;alert(fill("cup"));">run: fill("cup")</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="objects-and-arrays"></span>
|
||||
|
||||
<h2 id="objects-and-arrays">Objects and Arrays</h2>
|
||||
<p>The CoffeeScript literals for objects and arrays look very similar to their JavaScript cousins. When each property is listed on its own line, the commas are optional. Objects may be created using indentation instead of explicit braces, similar to <a href="http://yaml.org">YAML</a>.</p>
|
||||
<span class="bookmark" id="objects-and-arrays"></span>
|
||||
<h2>Objects and Arrays</h2><p>The CoffeeScript literals for objects and arrays look very similar to their JavaScript cousins. When each property is listed on its own line, the commas are optional. Objects may be created using indentation instead of explicit braces, similar to <a href="http://yaml.org">YAML</a>.</p>
|
||||
<div class='code'><pre><code>song = [<span class="string">"do"</span>, <span class="string">"re"</span>, <span class="string">"mi"</span>, <span class="string">"fa"</span>, <span class="string">"so"</span>]
|
||||
|
||||
singers = {Jagger: <span class="string">"Rock"</span>, Elvis: <span class="string">"Roll"</span>}
|
||||
|
@ -1080,10 +1063,8 @@ turtle = {
|
|||
|
||||
output = turtle.name + <span class="string">" wears an "</span> + turtle.mask + <span class="string">" mask. Watch out for his "</span> + turtle.weapon + <span class="string">"!"</span>;
|
||||
</code></pre><script>window.example3 = "name = \"Michelangelo\"\nmask = \"orange\"\nweapon = \"nunchuks\"\nturtle = {name, mask, weapon}\noutput = \"#{turtle.name} wears an #{turtle.mask} mask. Watch out for his #{turtle.weapon}!\"\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example3);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="lexical-scope"></span>
|
||||
|
||||
<h2 id="lexical-scoping-and-variable-safety">Lexical Scoping and Variable Safety</h2>
|
||||
<p>The CoffeeScript compiler takes care to make sure that all of your variables are properly declared within lexical scope — you never need to write <code>var</code> yourself.</p>
|
||||
<span class="bookmark" id="lexical-scope"></span>
|
||||
<h2>Lexical Scoping and Variable Safety</h2><p>The CoffeeScript compiler takes care to make sure that all of your variables are properly declared within lexical scope — you never need to write <code>var</code> yourself.</p>
|
||||
<div class='code'><pre><code>outer = <span class="number">1</span>
|
||||
<span class="function"><span class="title">changeNumbers</span> = -></span>
|
||||
inner = <span class="number">-1</span>
|
||||
|
@ -1116,10 +1097,8 @@ inner = changeNumbers();
|
|||
<p>Although suppressed within this documentation for clarity, all CoffeeScript output is wrapped in an anonymous function: <code>(function(){ … })();</code> This safety wrapper, combined with the automatic generation of the <code>var</code> keyword, make it exceedingly difficult to pollute the global namespace by accident.</p>
|
||||
<p>If you’d like to create top-level variables for other scripts to use, attach them as properties on <strong>window</strong>; attach them as properties on the <strong>exports</strong> object in CommonJS; or use an <a href="#modules"><code>export</code> statement</a>. If you’re targeting both CommonJS and the browser, the <strong>existential operator</strong> (covered below), gives you a reliable way to figure out where to add them: <code>exports ? this</code></p>
|
||||
|
||||
<span class="bookmark" id="conditionals"></span>
|
||||
|
||||
<h2 id="if-else-unless-and-conditional-assignment">If, Else, Unless, and Conditional Assignment</h2>
|
||||
<p><strong>If/else</strong> statements can be written without the use of parentheses and curly brackets. As with functions and other block expressions, multi-line conditionals are delimited by indentation. There’s also a handy postfix form, with the <code>if</code> or <code>unless</code> at the end.</p>
|
||||
<span class="bookmark" id="conditionals"></span>
|
||||
<h2>If, Else, Unless, and Conditional Assignment</h2><p><strong>If/else</strong> statements can be written without the use of parentheses and curly brackets. As with functions and other block expressions, multi-line conditionals are delimited by indentation. There’s also a handy postfix form, with the <code>if</code> or <code>unless</code> at the end.</p>
|
||||
<p>CoffeeScript can compile <strong>if</strong> statements into JavaScript expressions, using the ternary operator when possible, and closure wrapping otherwise. There is no explicit ternary statement in CoffeeScript — you simply use a regular <strong>if</strong> statement on a single line.</p>
|
||||
<div class='code'><pre><code>mood = greatlyImproved <span class="keyword">if</span> singing
|
||||
|
||||
|
@ -1145,10 +1124,8 @@ date = <span class="keyword">if</span> friday <span class="keyword">then</span>
|
|||
|
||||
date = friday ? sue : jill;
|
||||
</code></pre><script>window.example1 = "mood = greatlyImproved if singing\n\nif happy and knowsIt\n clapsHands()\n chaChaCha()\nelse\n showIt()\n\ndate = if friday then sue else jill\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example1);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="splats"></span>
|
||||
|
||||
<h2 id="splats-">Splats…</h2>
|
||||
<p>The JavaScript <strong>arguments object</strong> is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides splats <code>...</code>, both for function definition as well as invocation, making variable numbers of arguments a little bit more palatable.</p>
|
||||
<span class="bookmark" id="splats"></span>
|
||||
<h2>Splats…</h2><p>The JavaScript <strong>arguments object</strong> is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides splats <code>...</code>, both for function definition as well as invocation, making variable numbers of arguments a little bit more palatable.</p>
|
||||
<div class='code'><pre><code>gold = silver = rest = <span class="string">"unknown"</span>
|
||||
<span class="function">
|
||||
<span class="title">awardMedals</span> = <span class="params">(first, second, others...)</span> -></span>
|
||||
|
@ -1219,10 +1196,8 @@ alert("Silver: " + silver);
|
|||
|
||||
alert("The Field: " + rest);
|
||||
;">run</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="loops"></span>
|
||||
|
||||
<h2 id="loops-and-comprehensions">Loops and Comprehensions</h2>
|
||||
<p>Most of the loops you’ll write in CoffeeScript will be <strong>comprehensions</strong> over arrays, objects, and ranges. Comprehensions replace (and compile into) <strong>for</strong> loops, with optional guard clauses and the value of the current array index. Unlike for loops, array comprehensions are expressions, and can be returned and assigned.</p>
|
||||
<span class="bookmark" id="loops"></span>
|
||||
<h2>Loops and Comprehensions</h2><p>Most of the loops you’ll write in CoffeeScript will be <strong>comprehensions</strong> over arrays, objects, and ranges. Comprehensions replace (and compile into) <strong>for</strong> loops, with optional guard clauses and the value of the current array index. Unlike for loops, array comprehensions are expressions, and can be returned and assigned.</p>
|
||||
<div class='code'><pre><code><span class="comment"># Eat lunch.</span>
|
||||
eat food <span class="keyword">for</span> food <span class="keyword">in</span> [<span class="string">'toast'</span>, <span class="string">'cheese'</span>, <span class="string">'wine'</span>]
|
||||
|
||||
|
@ -1397,10 +1372,8 @@ fn = <span class="function"><span class="keyword">function</span>(<span class="p
|
|||
fn(filename);
|
||||
}
|
||||
</code></pre><script>window.example5 = "for filename in list\n do (filename) ->\n fs.readFile filename, (err, contents) ->\n compile filename, contents.toString()\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example5);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="slices"></span>
|
||||
|
||||
<h2 id="array-slicing-and-splicing-with-ranges">Array Slicing and Splicing with Ranges</h2>
|
||||
<p>Ranges can also be used to extract slices of arrays. With two dots (<code>3..6</code>), the range is inclusive (<code>3, 4, 5, 6</code>); with three dots (<code>3...6</code>), the range excludes the end (<code>3, 4, 5</code>). Slices indices have useful defaults. An omitted first index defaults to zero and an omitted second index defaults to the size of the array.</p>
|
||||
<span class="bookmark" id="slices"></span>
|
||||
<h2>Array Slicing and Splicing with Ranges</h2><p>Ranges can also be used to extract slices of arrays. With two dots (<code>3..6</code>), the range is inclusive (<code>3, 4, 5, 6</code>); with three dots (<code>3...6</code>), the range excludes the end (<code>3, 4, 5</code>). Slices indices have useful defaults. An omitted first index defaults to zero and an omitted second index defaults to the size of the array.</p>
|
||||
<div class='code'><pre><code>numbers = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]
|
||||
|
||||
start = numbers[<span class="number">0.</span><span class="number">.2</span>]
|
||||
|
@ -1448,10 +1421,8 @@ numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|||
[].splice.apply(numbers, [3, 4].concat(ref = [-3, -4, -5, -6])), ref;
|
||||
;alert(numbers);">run: numbers</div><br class='clear' /></div><p>Note that JavaScript strings are immutable, and can’t be spliced.</p>
|
||||
|
||||
<span class="bookmark" id="expressions"></span>
|
||||
|
||||
<h2 id="everything-is-an-expression-at-least-as-much-as-possible-">Everything is an Expression (at least, as much as possible)</h2>
|
||||
<p>You might have noticed how even though we don’t add return statements to CoffeeScript functions, they nonetheless return their final value. The CoffeeScript compiler tries to make sure that all statements in the language can be used as expressions. Watch how the <code>return</code> gets pushed down into each possible branch of execution in the function below.</p>
|
||||
<span class="bookmark" id="expressions"></span>
|
||||
<h2>Everything is an Expression (at least, as much as possible)</h2><p>You might have noticed how even though we don’t add return statements to CoffeeScript functions, they nonetheless return their final value. The CoffeeScript compiler tries to make sure that all statements in the language can be used as expressions. Watch how the <code>return</code> gets pushed down into each possible branch of execution in the function below.</p>
|
||||
<div class='code'><pre><code><span class="function"><span class="title">grade</span> = <span class="params">(student)</span> -></span>
|
||||
<span class="keyword">if</span> student.excellentWork
|
||||
<span class="string">"A+"</span>
|
||||
|
@ -1557,10 +1528,8 @@ alert((function() {
|
|||
})());
|
||||
;">run</div><br class='clear' /></div><p>There are a handful of statements in JavaScript that can’t be meaningfully converted into expressions, namely <code>break</code>, <code>continue</code>, and <code>return</code>. If you make use of them within a block of code, CoffeeScript won’t try to perform the conversion.</p>
|
||||
|
||||
<span class="bookmark" id="operators"></span>
|
||||
|
||||
<h2 id="operators-and-aliases">Operators and Aliases</h2>
|
||||
<p>Because the <code>==</code> operator frequently causes undesirable coercion, is intransitive, and has a different meaning than in other languages, CoffeeScript compiles <code>==</code> into <code>===</code>, and <code>!=</code> into <code>!==</code>. In addition, <code>is</code> compiles into <code>===</code>, and <code>isnt</code> into <code>!==</code>.</p>
|
||||
<span class="bookmark" id="operators"></span>
|
||||
<h2>Operators and Aliases</h2><p>Because the <code>==</code> operator frequently causes undesirable coercion, is intransitive, and has a different meaning than in other languages, CoffeeScript compiles <code>==</code> into <code>===</code>, and <code>!=</code> into <code>!==</code>. In addition, <code>is</code> compiles into <code>===</code>, and <code>isnt</code> into <code>!==</code>.</p>
|
||||
<p>You can use <code>not</code> as an alias for <code>!</code>.</p>
|
||||
<p>For logic, <code>and</code> compiles to <code>&&</code>, and <code>or</code> into <code>||</code>.</p>
|
||||
<p>Instead of a newline or semicolon, <code>then</code> can be used to separate conditions from expressions, in <strong>while</strong>, <strong>if</strong>/<strong>else</strong>, and <strong>switch</strong>/<strong>when</strong> statements.</p>
|
||||
|
@ -1736,10 +1705,8 @@ winner = <span class="literal">yes</span> <span class="keyword">if</span> pick <
|
|||
|
||||
print(inspect(<span class="string">"My name is "</span> + <span class="keyword">this</span>.name));
|
||||
</code></pre><script>window.example2 = "launch() if ignition is on\n\nvolume = 10 if band isnt SpinalTap\n\nletTheWildRumpusBegin() unless answer is no\n\nif car.speed < limit then accelerate()\n\nwinner = yes if pick in [47, 92, 13]\n\nprint inspect \"My name is #{@name}\"\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example2);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="existential-operator"></span>
|
||||
|
||||
<h2 id="the-existential-operator">The Existential Operator</h2>
|
||||
<p>It’s a little difficult to check for the existence of a variable in JavaScript. <code>if (variable) …</code> comes close, but fails for zero, the empty string, and false. CoffeeScript’s existential operator <code>?</code> returns true unless a variable is <strong>null</strong> or <strong>undefined</strong>, which makes it analogous to Ruby’s <code>nil?</code></p>
|
||||
<span class="bookmark" id="existential-operator"></span>
|
||||
<h2>The Existential Operator</h2><p>It’s a little difficult to check for the existence of a variable in JavaScript. <code>if (variable) …</code> comes close, but fails for zero, the empty string, and false. CoffeeScript’s existential operator <code>?</code> returns true unless a variable is <strong>null</strong> or <strong>undefined</strong>, which makes it analogous to Ruby’s <code>nil?</code></p>
|
||||
<p>It can also be used for safer conditional assignment than <code>||=</code> provides, for cases where you may be handling numbers or strings.</p>
|
||||
<div class='code'><pre><code>solipsism = <span class="literal">true</span> <span class="keyword">if</span> mind? <span class="keyword">and</span> <span class="keyword">not</span> world?
|
||||
|
||||
|
@ -1780,10 +1747,8 @@ footprints = typeof yeti !== "undefined" && yeti !== null ? yeti : &qu
|
|||
zip = <span class="keyword">typeof</span> lottery.drawWinner === <span class="string">"function"</span> ? (ref = lottery.drawWinner().address) != <span class="literal">null</span> ? ref.zipcode : <span class="keyword">void</span> <span class="number">0</span> : <span class="keyword">void</span> <span class="number">0</span>;
|
||||
</code></pre><script>window.example2 = "zip = lottery.drawWinner?().address?.zipcode\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example2);'>load</div><br class='clear' /></div><p>Soaking up nulls is similar to Ruby’s <a href="https://rubygems.org/gems/andand">andand gem</a>, and to the <a href="http://docs.groovy-lang.org/latest/html/documentation/index.html#_safe_navigation_operator">safe navigation operator</a> in Groovy.</p>
|
||||
|
||||
<span class="bookmark" id="classes"></span>
|
||||
|
||||
<h2 id="classes-inheritance-and-super">Classes, Inheritance, and Super</h2>
|
||||
<p>JavaScript’s prototypal inheritance has always been a bit of a brain-bender, with a whole family tree of libraries that provide a cleaner syntax for classical inheritance on top of JavaScript’s prototypes: <a href="http://code.google.com/p/base2/">Base2</a>, <a href="http://prototypejs.org/">Prototype.js</a>, <a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc. The libraries provide syntactic sugar, but the built-in inheritance would be completely usable if it weren’t for a couple of small exceptions: it’s awkward to call <strong>super</strong> (the prototype object’s implementation of the current function), and it’s awkward to correctly set the prototype chain.</p>
|
||||
<span class="bookmark" id="classes"></span>
|
||||
<h2>Classes, Inheritance, and Super</h2><p>JavaScript’s prototypal inheritance has always been a bit of a brain-bender, with a whole family tree of libraries that provide a cleaner syntax for classical inheritance on top of JavaScript’s prototypes: <a href="http://code.google.com/p/base2/">Base2</a>, <a href="http://prototypejs.org/">Prototype.js</a>, <a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc. The libraries provide syntactic sugar, but the built-in inheritance would be completely usable if it weren’t for a couple of small exceptions: it’s awkward to call <strong>super</strong> (the prototype object’s implementation of the current function), and it’s awkward to correctly set the prototype chain.</p>
|
||||
<p>Instead of repetitively attaching functions to a prototype, CoffeeScript provides a basic <code>class</code> structure that allows you to name your class, set the superclass, assign prototypal properties, and define the constructor, in a single assignable expression.</p>
|
||||
<p>Constructor functions are named, to better support helpful stack traces. In the first class in the example below, <code>this.constructor.name is "Animal"</code>.</p>
|
||||
<div class='code'><pre><code><span class="class"><span class="keyword">class</span> <span class="title">Animal</span></span>
|
||||
|
@ -1931,10 +1896,8 @@ tom.move();
|
|||
;alert("one_two".dasherize());">run: "one_two".dasherize()</div><br class='clear' /></div><p>Finally, class definitions are blocks of executable code, which make for interesting metaprogramming possibilities. Because in the context of a class definition, <code>this</code> is the class object itself (the constructor function), you can assign static properties by using
|
||||
<code>@property: value</code>, and call functions defined in parent classes: <code>@attr 'title', type: 'text'</code></p>
|
||||
|
||||
<span class="bookmark" id="destructuring"></span>
|
||||
|
||||
<h2 id="destructuring-assignment">Destructuring Assignment</h2>
|
||||
<p>Just like JavaScript (since ES2015), CoffeeScript has destructuring assignment syntax. When you assign an array or object literal to a value, CoffeeScript breaks up and matches both sides against each other, assigning the values on the right to the variables on the left. In the simplest case, it can be used for parallel assignment:</p>
|
||||
<span class="bookmark" id="destructuring"></span>
|
||||
<h2>Destructuring Assignment</h2><p>Just like JavaScript (since ES2015), CoffeeScript has destructuring assignment syntax. When you assign an array or object literal to a value, CoffeeScript breaks up and matches both sides against each other, assigning the values on the right to the variables on the left. In the simplest case, it can be used for parallel assignment:</p>
|
||||
<div class='code'><pre><code>theBait = <span class="number">1000</span>
|
||||
theSwitch = <span class="number">0</span>
|
||||
|
||||
|
@ -2080,10 +2043,8 @@ tim = new Person({
|
|||
});
|
||||
;alert(tim.age + " " + tim.height);">run: tim.age + " " + tim.height</div><br class='clear' /></div><p>The above example also demonstrates that if properties are missing in the destructured object or array, you can, just like in JavaScript, provide defaults. The difference with JavaScript is that CoffeeScript, as always, treats both null and undefined the same.</p>
|
||||
|
||||
<span class="bookmark" id="fat-arrow"></span>
|
||||
|
||||
<h2 id="bound-functions-generator-functions">Bound Functions, Generator Functions</h2>
|
||||
<p>In JavaScript, the <code>this</code> keyword is dynamically scoped to mean the object that the current function is attached to. If you pass a function as a callback or attach it to a different object, the original value of <code>this</code> will be lost. If you’re not familiar with this behavior, <a href="http://64.13.255.16/articles/scope_in_javascript/">this Digital Web article</a> gives a good overview of the quirks.</p>
|
||||
<span class="bookmark" id="fat-arrow"></span>
|
||||
<h2>Bound Functions, Generator Functions</h2><p>In JavaScript, the <code>this</code> keyword is dynamically scoped to mean the object that the current function is attached to. If you pass a function as a callback or attach it to a different object, the original value of <code>this</code> will be lost. If you’re not familiar with this behavior, <a href="http://64.13.255.16/articles/scope_in_javascript/">this Digital Web article</a> gives a good overview of the quirks.</p>
|
||||
<p>The fat arrow <code>=></code> can be used to both define a function, and to bind it to the current value of <code>this</code>, right on the spot. This is helpful when using callback-based libraries like Prototype or jQuery, for creating iterator functions to pass to <code>each</code>, or event-handler functions to use with <code>on</code>. Functions created with the fat arrow are able to access properties of the <code>this</code> where they’re defined.</p>
|
||||
<div class='code'><pre><code><span class="function"><span class="title">Account</span> = <span class="params">(customer, cart)</span> -></span>
|
||||
@customer = customer
|
||||
|
@ -2199,10 +2160,8 @@ getFibonacciNumbers = function(length) {
|
|||
return results;
|
||||
};
|
||||
;alert(getFibonacciNumbers(10));">run: getFibonacciNumbers(10)</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="embedded"></span>
|
||||
|
||||
<h2 id="embedded-javascript">Embedded JavaScript</h2>
|
||||
<p>Hopefully, you’ll never need to use it, but if you ever need to intersperse snippets of JavaScript within your CoffeeScript, you can use backticks to pass it straight through.</p>
|
||||
<span class="bookmark" id="embedded"></span>
|
||||
<h2>Embedded JavaScript</h2><p>Hopefully, you’ll never need to use it, but if you ever need to intersperse snippets of JavaScript within your CoffeeScript, you can use backticks to pass it straight through.</p>
|
||||
<div class='code'><pre><code>hi = `<span class="javascript"><span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{
|
||||
<span class="keyword">return</span> [<span class="built_in">document</span>.title, <span class="string">"Hello JavaScript"</span>].join(<span class="string">": "</span>);
|
||||
}</span>`
|
||||
|
@ -2250,10 +2209,8 @@ function time() {
|
|||
;
|
||||
|
||||
;alert(time());">run: time()</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="switch"></span>
|
||||
|
||||
<h2 id="switch-when-else">Switch/When/Else</h2>
|
||||
<p><strong>Switch</strong> statements in JavaScript are a bit awkward. You need to remember to <strong>break</strong> at the end of every <strong>case</strong> statement to avoid accidentally falling through to the default case. CoffeeScript prevents accidental fall-through, and can convert the <code>switch</code> into a returnable, assignable expression. The format is: <code>switch</code> condition, <code>when</code> clauses, <code>else</code> the default case.</p>
|
||||
<span class="bookmark" id="switch"></span>
|
||||
<h2>Switch/When/Else</h2><p><strong>Switch</strong> statements in JavaScript are a bit awkward. You need to remember to <strong>break</strong> at the end of every <strong>case</strong> statement to avoid accidentally falling through to the default case. CoffeeScript prevents accidental fall-through, and can convert the <code>switch</code> into a returnable, assignable expression. The format is: <code>switch</code> condition, <code>when</code> clauses, <code>else</code> the default case.</p>
|
||||
<p>As in Ruby, <strong>switch</strong> statements in CoffeeScript can take multiple values for each <strong>when</strong> clause. If any of the values match, the clause runs.</p>
|
||||
<div class='code'><pre><code><span class="keyword">switch</span> day
|
||||
<span class="keyword">when</span> <span class="string">"Mon"</span> <span class="keyword">then</span> go work
|
||||
|
@ -2316,10 +2273,8 @@ grade = (<span class="function"><span class="keyword">function</span>(<span clas
|
|||
}
|
||||
})();
|
||||
</code></pre><script>window.example2 = "score = 76\ngrade = switch\n when score < 60 then 'F'\n when score < 70 then 'D'\n when score < 80 then 'C'\n when score < 90 then 'B'\n else 'A'\n# grade == 'C'\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example2);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="try"></span>
|
||||
|
||||
<h2 id="try-catch-finally">Try/Catch/Finally</h2>
|
||||
<p>Try-expressions have the same semantics as try-statements in JavaScript, though in CoffeeScript, you may omit <em>both</em> the catch and finally parts. The catch part may also omit the error parameter if it is not needed.</p>
|
||||
<span class="bookmark" id="try"></span>
|
||||
<h2>Try/Catch/Finally</h2><p>Try-expressions have the same semantics as try-statements in JavaScript, though in CoffeeScript, you may omit <em>both</em> the catch and finally parts. The catch part may also omit the error parameter if it is not needed.</p>
|
||||
<div class='code'><pre><code><span class="keyword">try</span>
|
||||
allHellBreaksLoose()
|
||||
catsAndDogsLivingTogether()
|
||||
|
@ -2339,10 +2294,8 @@ grade = (<span class="function"><span class="keyword">function</span>(<span clas
|
|||
cleanUp();
|
||||
}
|
||||
</code></pre><script>window.example1 = "try\n allHellBreaksLoose()\n catsAndDogsLivingTogether()\ncatch error\n print error\nfinally\n cleanUp()\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example1);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="comparisons"></span>
|
||||
|
||||
<h2 id="chained-comparisons">Chained Comparisons</h2>
|
||||
<p>CoffeeScript borrows <a href="http://docs.python.org/reference/expressions.html#notin">chained comparisons</a> from Python — making it easy to test if a value falls within a certain range.</p>
|
||||
<span class="bookmark" id="comparisons"></span>
|
||||
<h2>Chained Comparisons</h2><p>CoffeeScript borrows <a href="http://docs.python.org/reference/expressions.html#notin">chained comparisons</a> from Python — making it easy to test if a value falls within a certain range.</p>
|
||||
<div class='code'><pre><code>cholesterol = <span class="number">127</span>
|
||||
|
||||
healthy = <span class="number">200</span> > cholesterol > <span class="number">60</span>
|
||||
|
@ -2357,10 +2310,8 @@ cholesterol = 127;
|
|||
|
||||
healthy = (200 > cholesterol && cholesterol > 60);
|
||||
;alert(healthy);">run: healthy</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="strings"></span>
|
||||
|
||||
<h2 id="string-interpolation-block-strings-and-block-comments">String Interpolation, Block Strings, and Block Comments</h2>
|
||||
<p>Ruby-style string interpolation is included in CoffeeScript. Double-quoted strings allow for interpolated values, using <code>#{ … }</code>, and single-quoted strings are literal. You may even use interpolation in object keys.</p>
|
||||
<span class="bookmark" id="strings"></span>
|
||||
<h2>String Interpolation, Block Strings, and Block Comments</h2><p>Ruby-style string interpolation is included in CoffeeScript. Double-quoted strings allow for interpolated values, using <code>#{ … }</code>, and single-quoted strings are literal. You may even use interpolation in object keys.</p>
|
||||
<div class='code'><pre><code>author = <span class="string">"Wittgenstein"</span>
|
||||
quote = <span class="string">"A picture is a fact. -- <span class="subst">#{ author }</span>"</span>
|
||||
|
||||
|
@ -2417,10 +2368,8 @@ Released under the MIT License
|
|||
*/</span>
|
||||
|
||||
</code></pre><script>window.example4 = "###\nSkinnyMochaHalfCaffScript Compiler v1.0\nReleased under the MIT License\n###\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example4);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="tagged-template-literals"></span>
|
||||
|
||||
<h2 id="tagged-template-literals">Tagged Template Literals</h2>
|
||||
<p>CoffeeScript supports <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals">ES2015 tagged template literals</a>, which enable customized string interpolation. If you immediately prefix a string with a function name (no space between the two), CoffeeScript will output this “function plus string” combination as an ES2015 tagged template literal, which will <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals">behave accordingly</a>: the function is called, with the parameters being the input text and expression parts that make up the interpolated string. The function can then assemble these parts into an output string, providing custom string interpolation.</p>
|
||||
<span class="bookmark" id="tagged-template-literals"></span>
|
||||
<h2>Tagged Template Literals</h2><p>CoffeeScript supports <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals">ES2015 tagged template literals</a>, which enable customized string interpolation. If you immediately prefix a string with a function name (no space between the two), CoffeeScript will output this “function plus string” combination as an ES2015 tagged template literal, which will <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals">behave accordingly</a>: the function is called, with the parameters being the input text and expression parts that make up the interpolated string. The function can then assemble these parts into an output string, providing custom string interpolation.</p>
|
||||
<p>Be aware that the CoffeeScript compiler is outputting ES2015 syntax for this feature, so your target JavaScript runtime(s) must support this syntax for your code to work; or you could use tools like <a href="http://babeljs.io/">Babel</a> or <a href="https://github.com/google/traceur-compiler">Traceur Compiler</a> to convert this ES2015 syntax into compatible JavaScript.</p>
|
||||
<div class='code'><pre><code><span class="function"><span class="title">upperCaseExpr</span> = <span class="params">(textParts, expressions...)</span> -></span>
|
||||
textParts.reduce (text, textPart, i) ->
|
||||
|
@ -2459,10 +2408,8 @@ greet = function(name, adjective) {
|
|||
return upperCaseExpr`Hi ${name}. You look ${adjective}!`;
|
||||
};
|
||||
;alert(greet("greg", "awesome"));">run: greet("greg", "awesome")</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="regexes"></span>
|
||||
|
||||
<h2 id="block-regular-expressions">Block Regular Expressions</h2>
|
||||
<p>Similar to block strings and comments, CoffeeScript supports block regexes — extended regular expressions that ignore internal whitespace and can contain comments and interpolation. Modeled after Perl’s <code>/x</code> modifier, CoffeeScript’s block regexes are delimited by <code>///</code> and go a long way towards making complex regular expressions readable. To quote from the CoffeeScript source:</p>
|
||||
<span class="bookmark" id="regexes"></span>
|
||||
<h2>Block Regular Expressions</h2><p>Similar to block strings and comments, CoffeeScript supports block regexes — extended regular expressions that ignore internal whitespace and can contain comments and interpolation. Modeled after Perl’s <code>/x</code> modifier, CoffeeScript’s block regexes are delimited by <code>///</code> and go a long way towards making complex regular expressions readable. To quote from the CoffeeScript source:</p>
|
||||
<div class='code'><pre><code>OPERATOR = <span class="regexp">/// ^ (
|
||||
?: [-=]> <span class="comment"># function</span>
|
||||
| [-+*/%<>&|^!?=]= <span class="comment"># compound assign / compare</span>
|
||||
|
@ -2476,10 +2423,8 @@ greet = function(name, adjective) {
|
|||
|
||||
OPERATOR = <span class="regexp">/^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/</span>;
|
||||
</code></pre><script>window.example1 = "OPERATOR = /// ^ (\n ?: [-=]> # function\n | [-+*/%<>&|^!?=]= # compound assign / compare\n | >>>=? # zero-fill right shift\n | ([-+:])\\1 # doubles\n | ([&|<>])\\2=? # logic / shift\n | \\?\\. # soak access\n | \\.{2,3} # range or splat\n) ///\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example1);'>load</div><br class='clear' /></div>
|
||||
<span class="bookmark" id="modules"></span>
|
||||
|
||||
<h2 id="modules">Modules</h2>
|
||||
<p>ES2015 modules are supported in CoffeeScript, with very similar <code>import</code> and <code>export</code> syntax:</p>
|
||||
<span class="bookmark" id="modules"></span>
|
||||
<h2>Modules</h2><p>ES2015 modules are supported in CoffeeScript, with very similar <code>import</code> and <code>export</code> syntax:</p>
|
||||
<div class='code'><pre><code><span class="keyword">import</span> <span class="string">'local-file.coffee'</span>
|
||||
<span class="keyword">import</span> <span class="string">'coffee-script'</span>
|
||||
|
||||
|
@ -2571,9 +2516,7 @@ OPERATOR = <span class="regexp">/^(?:[-=]>|[-+*\/%<>&|^!?=]=|>&g
|
|||
<p>Also note that any file with an <code>import</code> or <code>export</code> statement will be output without a <a href="#lexical-scope">top-level function safety wrapper</a>; in other words, importing or exporting modules will automatically trigger <a href="#usage">bare</a> mode for that file. This is because per the ES2015 spec, <code>import</code> or <code>export</code> statements must occur at the topmost scope.</p>
|
||||
|
||||
<span class="bookmark" id="cake"></span>
|
||||
|
||||
<h2 id="cake-and-cakefiles">Cake, and Cakefiles</h2>
|
||||
<p>CoffeeScript includes a (very) simple build system similar to <a href="http://www.gnu.org/software/make/">Make</a> and <a href="http://rake.rubyforge.org/">Rake</a>. Naturally, it’s called Cake, and is used for the tasks that build and test the CoffeeScript language itself. Tasks are defined in a file named <code>Cakefile</code>, and can be invoked by running <code>cake [task]</code> from within the directory. To print a list of all the tasks and options, just type <code>cake</code>.</p>
|
||||
<h2>Cake, and Cakefiles</h2><p>CoffeeScript includes a (very) simple build system similar to <a href="http://www.gnu.org/software/make/">Make</a> and <a href="http://rake.rubyforge.org/">Rake</a>. Naturally, it’s called Cake, and is used for the tasks that build and test the CoffeeScript language itself. Tasks are defined in a file named <code>Cakefile</code>, and can be invoked by running <code>cake [task]</code> from within the directory. To print a list of all the tasks and options, just type <code>cake</code>.</p>
|
||||
<p>Task definitions are written in CoffeeScript, so you can put arbitrary code in your Cakefile. Define a task with a name, a long description, and the function to invoke when the task is run. If your task takes a command-line option, you can define the option with short and long flags, and it will be made available in the <code>options</code> object. Here’s a task that uses the Node.js API to rebuild CoffeeScript’s parser:</p>
|
||||
<div class='code'><pre><code>fs = <span class="built_in">require</span> <span class="string">'fs'</span>
|
||||
|
||||
|
@ -2600,22 +2543,16 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
|
|||
</code></pre><script>window.example1 = "fs = require 'fs'\n\noption '-o', '--output [DIR]', 'directory for compiled code'\n\ntask 'build:parser', 'rebuild the Jison parser', (options) ->\n require 'jison'\n code = require('./lib/grammar').parser.generate()\n dir = options.output or 'lib'\n fs.writeFile \"#{dir}/parser.js\", code\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example1);'>load</div><br class='clear' /></div><p>If you need to invoke one task before another — for example, running <code>build</code> before <code>test</code>, you can use the <code>invoke</code> function: <code>invoke 'build'</code>. Cake tasks are a minimal way to expose your CoffeeScript functions to the command line, so <a href="v1/annotated-source/cake.html">don’t expect any fanciness built-in</a>. If you need dependencies, or async callbacks, it’s best to put them in your code itself — not the cake task.</p>
|
||||
|
||||
<span class="bookmark" id="source-maps"></span>
|
||||
|
||||
<h2 id="source-maps">Source Maps</h2>
|
||||
<p>CoffeeScript 1.6.1 and above include support for generating source maps, a way to tell your JavaScript engine what part of your CoffeeScript program matches up with the code being evaluated. Browsers that support it can automatically use source maps to show your original source code in the debugger. To generate source maps alongside your JavaScript files, pass the <code>--map</code> or <code>-m</code> flag to the compiler.</p>
|
||||
<h2>Source Maps</h2><p>CoffeeScript 1.6.1 and above include support for generating source maps, a way to tell your JavaScript engine what part of your CoffeeScript program matches up with the code being evaluated. Browsers that support it can automatically use source maps to show your original source code in the debugger. To generate source maps alongside your JavaScript files, pass the <code>--map</code> or <code>-m</code> flag to the compiler.</p>
|
||||
<p>For a full introduction to source maps, how they work, and how to hook them up in your browser, read the <a href="http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/">HTML5 Tutorial</a>.</p>
|
||||
|
||||
<span class="bookmark" id="scripts"></span>
|
||||
|
||||
<h2 id="-text-coffeescript-script-tags">"text/coffeescript" Script Tags</h2>
|
||||
<p>While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using <code><script type="text/coffeescript"></code> tags. The source includes a compressed and minified version of the compiler (<a href="v1/browser-compiler/coffee-script.js">Download current version here, 51k when gzipped</a>) as <code>v1/browser-compiler/coffee-script.js</code>. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.</p>
|
||||
<h2>"text/coffeescript" Script Tags</h2><p>While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using <code><script type="text/coffeescript"></code> tags. The source includes a compressed and minified version of the compiler (<a href="v1/browser-compiler/coffee-script.js">Download current version here, 51k when gzipped</a>) as <code>v1/browser-compiler/coffee-script.js</code>. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.</p>
|
||||
<p>In fact, the little bit of glue script that runs “Try CoffeeScript” above, as well as the jQuery for the menu, is implemented in just this way. View source and look at the bottom of the page to see the example. Including the script also gives you access to <code>CoffeeScript.compile()</code> so you can pop open Firebug and try compiling some strings.</p>
|
||||
<p>The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the <code>window</code> object.</p>
|
||||
|
||||
<span class="bookmark" id="resources"></span>
|
||||
|
||||
<h2 id="books">Books</h2>
|
||||
<p>There are a number of excellent resources to help you get started with CoffeeScript, some of which are freely available online.</p>
|
||||
<h2>Books</h2><p>There are a number of excellent resources to help you get started with CoffeeScript, some of which are freely available online.</p>
|
||||
<ul>
|
||||
<li><a href="http://arcturo.github.com/library/coffeescript/">The Little Book on CoffeeScript</a> is a brief 5-chapter introduction to CoffeeScript, written with great clarity and precision by <a href="http://alexmaccaw.co.uk/">Alex MacCaw</a>.</li>
|
||||
<li><a href="http://autotelicum.github.com/Smooth-CoffeeScript/">Smooth CoffeeScript</a> is a reimagination of the excellent book <a href="http://eloquentjavascript.net/">Eloquent JavaScript</a>, as if it had been written in CoffeeScript instead. Covers language features as well as the functional and object oriented programming styles. By <a href="https://github.com/autotelicum">E. Hoigaard</a>.</li>
|
||||
|
@ -2629,18 +2566,14 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
|
|||
</ul>
|
||||
|
||||
<span class="bookmark" id="screencasts"></span>
|
||||
|
||||
<h2 id="screencasts">Screencasts</h2>
|
||||
<ul>
|
||||
<h2>Screencasts</h2><ul>
|
||||
<li><a href="http://coffeescript.codeschool.com">A Sip of CoffeeScript</a> is a <a href="http://www.codeschool.com">Code School Course</a> which combines 6 screencasts with in-browser coding to make learning fun. The first level is free to try out.</li>
|
||||
<li><a href="http://peepcode.com/products/coffeescript">Meet CoffeeScript</a> is a 75-minute long screencast by <a href="http://peepcode.com/">PeepCode</a>. Highly memorable for its animations which demonstrate transforming CoffeeScript into the equivalent JS.</li>
|
||||
<li>If you’re looking for less of a time commitment, RailsCasts’ <a href="http://railscasts.com/episodes/267-coffeescript-basics">CoffeeScript Basics</a> should have you covered, hitting all of the important notes about CoffeeScript in 11 minutes.</li>
|
||||
</ul>
|
||||
|
||||
<span class="bookmark" id="examples"></span>
|
||||
|
||||
<h2 id="examples">Examples</h2>
|
||||
<p>The <a href="https://github.com/trending?l=coffeescript&since=monthly">best list of open-source CoffeeScript examples</a> can be found on GitHub. But just to throw out a few more:</p>
|
||||
<h2>Examples</h2><p>The <a href="https://github.com/trending?l=coffeescript&since=monthly">best list of open-source CoffeeScript examples</a> can be found on GitHub. But just to throw out a few more:</p>
|
||||
<ul>
|
||||
<li><strong>GitHub</strong>’s <a href="http://hubot.github.com/">Hubot</a>, a friendly IRC robot that can perform any number of useful and useless tasks.</li>
|
||||
<li><strong>sstephenson</strong>’s <a href="http://pow.cx/">Pow</a>, a zero-configuration Rack server, with comprehensive annotated source.</li>
|
||||
|
@ -2652,9 +2585,7 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
|
|||
</ul>
|
||||
|
||||
<span class="bookmark" id="additional-resources"></span>
|
||||
|
||||
<h2 id="resources">Resources</h2>
|
||||
<ul>
|
||||
<h2>Resources</h2><ul>
|
||||
<li><p><a href="http://github.com/jashkenas/coffeescript/">Source Code</a><br>
|
||||
Use <code>bin/coffee</code> to test your changes,<br>
|
||||
<code>bin/cake test</code> to run the test suite,<br>
|
||||
|
@ -2679,15 +2610,11 @@ The CoffeeScript logo is available in SVG for use in presentations.</li>
|
|||
</ul>
|
||||
|
||||
<span class="bookmark" id="chat"></span>
|
||||
|
||||
<h2 id="web-chat-irc-">Web Chat (IRC)</h2>
|
||||
<p>Quick help and advice can usually be found in the CoffeeScript IRC room. Join <code>#coffeescript</code> on <code>irc.freenode.net</code>, or click the button below to open a webchat session on this page.</p>
|
||||
<h2>Web Chat (IRC)</h2><p>Quick help and advice can usually be found in the CoffeeScript IRC room. Join <code>#coffeescript</code> on <code>irc.freenode.net</code>, or click the button below to open a webchat session on this page.</p>
|
||||
<button id="open_webchat">click to open #coffeescript</button>
|
||||
|
||||
<span class="bookmark" id="changelog"></span>
|
||||
|
||||
<h2 id="change-log">Change Log</h2>
|
||||
<div class="anchor" id="1.12.1"></div>
|
||||
<h2>Change Log</h2><div class="anchor" id="1.12.1"></div>
|
||||
<h2 class="header">
|
||||
<a href="https://github.com/jashkenas/coffeescript/compare/1.12.0...1.12.1">1.12.1</a>
|
||||
<span class="timestamp"> — <time datetime="2016-12-07">December 7, 2016</time></span>
|
||||
|
|
|
@ -80,41 +80,76 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<%= htmlFor('introduction', 'top') %>
|
||||
<%= htmlFor('overview') %>
|
||||
<%= htmlFor('installation') %>
|
||||
<%= htmlFor('usage') %>
|
||||
<%= htmlFor('literate') %>
|
||||
<%= htmlFor('language') %>
|
||||
<%= htmlFor('functions', 'literals') %>
|
||||
<%= htmlFor('objects_and_arrays') %>
|
||||
<%= htmlFor('lexical_scope') %>
|
||||
<%= htmlFor('conditionals') %>
|
||||
<%= htmlFor('splats') %>
|
||||
<%= htmlFor('loops') %>
|
||||
<%= htmlFor('slices') %>
|
||||
<%= htmlFor('expressions') %>
|
||||
<%= htmlFor('operators') %>
|
||||
<%= htmlFor('existential_operator') %>
|
||||
<%= htmlFor('classes') %>
|
||||
<%= htmlFor('destructuring') %>
|
||||
<%= htmlFor('fat_arrow') %>
|
||||
<%= htmlFor('embedded') %>
|
||||
<%= htmlFor('switch') %>
|
||||
<%= htmlFor('try') %>
|
||||
<%= htmlFor('comparisons') %>
|
||||
<%= htmlFor('strings') %>
|
||||
<%= htmlFor('tagged_template_literals') %>
|
||||
<%= htmlFor('heregexes', 'regexes') %>
|
||||
<%= htmlFor('modules') %>
|
||||
<%= htmlFor('cake') %>
|
||||
<%= htmlFor('source_maps') %>
|
||||
<%= htmlFor('scripts') %>
|
||||
<%= htmlFor('books', 'resources') %>
|
||||
<%= htmlFor('screencasts') %>
|
||||
<%= htmlFor('examples') %>
|
||||
<%= htmlFor('resources', 'additional-resources') %>
|
||||
<%= htmlFor('chat') %>
|
||||
<%= htmlFor('changelog') %>
|
||||
<div id="top" class="container">
|
||||
<span class="bookmark" id="overview"></span>
|
||||
<%= htmlFor('introduction') %>
|
||||
<%= htmlFor('overview') %>
|
||||
<span class="bookmark" id="installation"></span>
|
||||
<%= htmlFor('installation') %>
|
||||
<span class="bookmark" id="usage"></span>
|
||||
<%= htmlFor('usage') %>
|
||||
<span class="bookmark" id="literate"></span>
|
||||
<%= htmlFor('literate') %>
|
||||
<span class="bookmark" id="language"></span>
|
||||
<%= htmlFor('language') %>
|
||||
<span class="bookmark" id="literals"></span>
|
||||
<%= htmlFor('functions') %>
|
||||
<span class="bookmark" id="objects-and-arrays"></span>
|
||||
<%= htmlFor('objects_and_arrays') %>
|
||||
<span class="bookmark" id="lexical-scope"></span>
|
||||
<%= htmlFor('lexical_scope') %>
|
||||
<span class="bookmark" id="conditionals"></span>
|
||||
<%= htmlFor('conditionals') %>
|
||||
<span class="bookmark" id="splats"></span>
|
||||
<%= htmlFor('splats') %>
|
||||
<span class="bookmark" id="loops"></span>
|
||||
<%= htmlFor('loops') %>
|
||||
<span class="bookmark" id="slices"></span>
|
||||
<%= htmlFor('slices') %>
|
||||
<span class="bookmark" id="expressions"></span>
|
||||
<%= htmlFor('expressions') %>
|
||||
<span class="bookmark" id="operators"></span>
|
||||
<%= htmlFor('operators') %>
|
||||
<span class="bookmark" id="existential-operator"></span>
|
||||
<%= htmlFor('existential_operator') %>
|
||||
<span class="bookmark" id="classes"></span>
|
||||
<%= htmlFor('classes') %>
|
||||
<span class="bookmark" id="destructuring"></span>
|
||||
<%= htmlFor('destructuring') %>
|
||||
<span class="bookmark" id="fat-arrow"></span>
|
||||
<%= htmlFor('fat_arrow') %>
|
||||
<span class="bookmark" id="embedded"></span>
|
||||
<%= htmlFor('embedded') %>
|
||||
<span class="bookmark" id="switch"></span>
|
||||
<%= htmlFor('switch') %>
|
||||
<span class="bookmark" id="try"></span>
|
||||
<%= htmlFor('try') %>
|
||||
<span class="bookmark" id="comparisons"></span>
|
||||
<%= htmlFor('comparisons') %>
|
||||
<span class="bookmark" id="strings"></span>
|
||||
<%= htmlFor('strings') %>
|
||||
<span class="bookmark" id="tagged-template-literals"></span>
|
||||
<%= htmlFor('tagged_template_literals') %>
|
||||
<span class="bookmark" id="regexes"></span>
|
||||
<%= htmlFor('heregexes') %>
|
||||
<span class="bookmark" id="modules"></span>
|
||||
<%= htmlFor('modules') %>
|
||||
<span class="bookmark" id="cake"></span>
|
||||
<%= htmlFor('cake') %>
|
||||
<span class="bookmark" id="source-maps"></span>
|
||||
<%= htmlFor('source_maps') %>
|
||||
<span class="bookmark" id="scripts"></span>
|
||||
<%= htmlFor('scripts') %>
|
||||
<span class="bookmark" id="resources"></span>
|
||||
<%= htmlFor('books') %>
|
||||
<span class="bookmark" id="screencasts"></span>
|
||||
<%= htmlFor('screencasts') %>
|
||||
<span class="bookmark" id="examples"></span>
|
||||
<%= htmlFor('examples') %>
|
||||
<span class="bookmark" id="additional-resources"></span>
|
||||
<%= htmlFor('resources') %>
|
||||
<span class="bookmark" id="chat"></span>
|
||||
<%= htmlFor('chat') %>
|
||||
<span class="bookmark" id="changelog"></span>
|
||||
<%= htmlFor('changelog') %>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue