1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

first pass at 0.2.0 docs

This commit is contained in:
Jeremy Ashkenas 2010-01-04 22:19:45 -05:00
parent 3e24cef69f
commit 6e63a18f86
21 changed files with 430 additions and 116 deletions

View file

@ -1,5 +1,7 @@
# Eat lunch. # Eat lunch.
lunch: this.eat(food) for food in ['toast', 'cheese', 'wine'] lunch: eat(food) for food in ['toast', 'cheese', 'wine']
# Zebra-stripe a table. # Naive collision detection.
highlight(row) for row, i in table when i % 2 is 0 for roid in asteroids
for roid2 in asteroids when roid isnt roid2
roid.explode() if roid.overlaps(roid2)

View file

@ -0,0 +1 @@
solipsism: true if mind? and not world?

View file

@ -0,0 +1,3 @@
# The first ten global properties.
globals: (name for property, name in window)[0...10]

View file

@ -0,0 +1,6 @@
alert(
try
nonexistent / undefined
catch error
"The error is: " + error
)

View file

@ -0,0 +1,3 @@
years_old: {max: 10, ida: 9, tim: 11}
ages: child + " is " + age for age, child in years_old

View file

@ -1,6 +1,13 @@
song: ["do", "re", "mi", "fa", "so"] song: ["do", "re", "mi", "fa", "so"]
ages: { ages: {
max: 10 max: 10
ida: 9 ida: 9
tim: 11 tim: 11
} }
matrix: [
1, 0, 1
0, 0, 1
1, 1, 0
]

View file

@ -0,0 +1,3 @@
for i in [0...eggs.length] by 12
dozen_eggs: eggs[i...i+12]
deliver(new egg_carton(dozen))

View file

@ -1,5 +1,5 @@
num: 1 num: 1
change_numbers: => change_numbers: =>
num: 2 new_num: -1
new_num: 3 num: 10
new_num: change_numbers() new_num: change_numbers()

View file

@ -0,0 +1,5 @@
numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers[3..6]: [-3, -4, -5, -6]

View file

@ -74,17 +74,18 @@
<p> <p>
<a href="#overview">Mini Overview</a><br /> <a href="#overview">Mini Overview</a><br />
<a href="#installation">Installation and Usage</a><br /> <a href="#installation">Installation and Usage</a><br />
<a href="#punctuation">Punctuation Primer</a><br /> <a href="#whitespace">Significant Whitespace</a><br />
<a href="#functions">Functions and Invocation</a><br /> <a href="#functions">Functions and Invocation</a><br />
<a href="#assignment">Assignment</a><br /> <a href="#assignment">Assignment</a><br />
<a href="#objects_and_arrays">Objects and Arrays</a><br /> <a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br /> <a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br /> <a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#existence">The Existence Operator</a><br />
<a href="#expressions">Everything is an Expression</a><br /> <a href="#expressions">Everything is an Expression</a><br />
<a href="#aliases">Aliases</a><br /> <a href="#aliases">Aliases</a><br />
<a href="#while">While Loops</a><br /> <a href="#while">While Loops</a><br />
<a href="#array_comprehensions">Array Comprehensions</a><br /> <a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a><br />
<a href="#slice">Slicing Arrays with Ranges</a><br /> <a href="#slice_splice">Array Slicing and Splicing with Ranges</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br /> <a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br /> <a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/When/Else</a><br /> <a href="#switch">Switch/When/Else</a><br />
@ -225,22 +226,22 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</i> </i>
</p> </p>
<p id="punctuation"> <p id="whitespace">
<b class="header">Punctuation Primer</b> <b class="header">Significant Whitespace</b>
You don't need to use semicolons <tt>;</tt> to terminate expressions, ending CoffeeScript uses Python-style significant whitespace: You don't need to
the line will do just as well. All other whitespace is use semicolons <tt>;</tt> to terminate expressions, ending
not significant. Instead of using curly braces <tt>{ }</tt> the line will do just as well. Semicolons can still be used to fit
to delimit a block of code, use a period <tt>.</tt> to mark the end of a multiple expressions onto a single line. Instead of using curly braces
block, for <tt>{ }</tt> to delimit a block of code (like <a href="#functions">functions</a>,
<a href="#functions">functions</a>,
<a href="#conditionals">if-statements</a>, <a href="#conditionals">if-statements</a>,
<a href="#switch">switch</a>, and <a href="#try">try/catch</a>. <a href="#switch">switch</a>, and <a href="#try">try/catch</a>),
use indentation.
</p> </p>
<p id="functions"> <p id="functions">
<b class="header">Functions and Invocation</b> <b class="header">Functions and Invocation</b>
Functions are defined by a list of parameters, an arrow, and the Functions are defined by a list of parameters, an arrow, and the
function body. The empty function looks like this: <tt>=>.</tt> function body. The empty function looks like this: <tt>=></tt>
</p> </p>
<%= code_for('functions', 'cube(5)') %> <%= code_for('functions', 'cube(5)') %>
@ -252,8 +253,8 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('assignment', 'greeting') %> <%= code_for('assignment', 'greeting') %>
<p> <p>
Declarations of new variables are pushed up to the top of the current scope, Declarations of new variables are pushed up to the top of the nearest
so that assignments may always be used within expressions. lexical scope, so that assignment may always be used within expressions.
</p> </p>
<p id="objects_and_arrays"> <p id="objects_and_arrays">
@ -261,7 +262,8 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
Object and Array literals look very similar to their JavaScript cousins. Object and Array literals look very similar to their JavaScript cousins.
When you spread out each assignment on a separate line, the commas are When you spread out each assignment on a separate line, the commas are
optional. In this way, assigning object properties looks the same as optional. In this way, assigning object properties looks the same as
assigning local variables. assigning local variables, and can be moved around freely. You can mix
and match the two styles.
</p> </p>
<%= code_for('objects_and_arrays', 'song.join(",")') %> <%= code_for('objects_and_arrays', 'song.join(",")') %>
@ -273,25 +275,29 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('scope', 'new_num') %> <%= code_for('scope', 'new_num') %>
<p> <p>
Notice how the variables are declared with <tt>var</tt> the first time Notice how the all of the variable declarations have been pushed up to
they appear. The second reference of <b>num</b>, within the function, the top of the closest scope, the first time they appear.
is not redeclared because <b>num</b> is still in scope. As opposed <b>num</b> is not redeclared within the inner function, because it's
to the second occurrence of <b>new_num</b>, in the last line. already in scope; the <b>new_num</b> within the function, on the other hand,
should not be able to change the value of the external variable of the same name, and
therefore has a declaration of its own.
</p> </p>
<p> <p>
Although suppressed within this documentation for clarity, all Although suppressed within this documentation for clarity, all
CoffeeScript output is wrapped in an anonymous function: CoffeeScript output is wrapped in an anonymous function:
<tt>(function(){ ... })();</tt> This safety wrapper, combined with the <tt>(function(){ ... })();</tt> This safety wrapper, combined with the
automatic generation of the <tt>var</tt> keyword, make it exceedingly difficult automatic generation of the <tt>var</tt> keyword, make it exceedingly difficult
to pollute the global namespace by accident. to pollute the global namespace by accident. If you'd like to create
global variables, attach them as properties on <b>window</b>,
or on the <b>exports</b> object in CommonJS.
</p> </p>
<p id="conditionals"> <p id="conditionals">
<b class="header">Conditionals, Ternaries, and Conditional Assignment</b> <b class="header">Conditionals, Ternaries, and Conditional Assignment</b>
<b>If/else</b> statements can be written without the use of parentheses and <b>If/else</b> statements can be written without the use of parentheses and
curly brackets. As with functions and other block expressions, conditionals curly brackets. As with functions and other block expressions,
are closed with periods. No period is necessary when using the single-line multi-line conditionals are delimited by indentation. There's also a handy
postfix form, with the <tt>if</tt> at the end. postfix form, with the <tt>if</tt> or <tt>unless</tt> at the end.
</p> </p>
<p> <p>
CoffeeScript will compile <b>if</b> statements using the ternary operator CoffeeScript will compile <b>if</b> statements using the ternary operator
@ -299,12 +305,22 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('conditionals') %> <%= code_for('conditionals') %>
<p> <p>
The conditional assignment operators are available: <tt>||=</tt>, The conditional assignment operators are included: <tt>||=</tt>,
which only assigns a value to a variable if the variable's current value which only assigns a value to a variable if the variable's current value
is falsy, and <tt>&amp;&amp;=</tt>, which only replaces the value of is falsy, and <tt>&amp;&amp;=</tt>, which only replaces the value of
truthy variables. truthy variables.
</p> </p>
<p id="existence">
<b class="header">The Existence Operator</b>
It's a little difficult to check for the existence of a variable in
JavaScript. <tt>if (variable) ...</tt> comes close, but fails for zero,
the empty string, and false. The existence operator <tt>?</tt> returns true unless
a variable is <b>null</b> or <b>undefined</b>, which makes it analogous
to <b>nil?</b> in Ruby.
</p>
<%= code_for('existence') %>
<p id="expressions"> <p id="expressions">
<b class="header">Everything is an Expression (at least, as much as possible)</b> <b class="header">Everything is an Expression (at least, as much as possible)</b>
You might have noticed how even though we don't add return statements You might have noticed how even though we don't add return statements
@ -316,14 +332,22 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('expressions', 'eldest') %> <%= code_for('expressions', 'eldest') %>
<p> <p>
The same mechanism is used to push down assignment through <b>switch</b> Because variable declarations occur at the top of scope, assignment can
statements, and <b>if-elses</b> (although the ternary operator is preferred). be used within expressions, even for variables that haven't been seen before:
Another part of manipulating assignment statements is
CoffeeScript's declaration of new variables at the top of the
current scope. This allows assignment to be used as a piece of an
expression.
</p> </p>
<%= code_for('expressions_assignment', 'six') %> <%= code_for('expressions_assignment', 'six') %>
<p>
Things that would otherwise be statements in JavaScript, when used
as part of an expression in CoffeeScript, are converted into expressions
by wrapping them in a closure. This lets you do useful things, like assign
the result of a comprehension to a variable:
</p>
<%= code_for('expressions_comprehension', 'globals') %>
<p>
As well as silly things, like passing a <b>try/catch</b> statement directly
into a function call:
</p>
<%= code_for('expressions_try', true) %>
<p id="aliases"> <p id="aliases">
<b class="header">Aliases</b> <b class="header">Aliases</b>
@ -367,8 +391,8 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<b>each</b> (<b>forEach</b>) style iterators, or... <b>each</b> (<b>forEach</b>) style iterators, or...
</p> </p>
<p id="array_comprehensions"> <p id="comprehensions">
<b class="header">Array Comprehensions</b> <b class="header">Comprehensions (Arrays, Objects, and Ranges)</b>
For your looping needs, CoffeeScript provides array comprehensions For your looping needs, CoffeeScript provides array comprehensions
similar to Python's. They replace (and compile into) <b>for</b> loops, with similar to Python's. They replace (and compile into) <b>for</b> loops, with
optional guard clauses and the value of the current array index. optional guard clauses and the value of the current array index.
@ -378,13 +402,19 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('array_comprehensions') %> <%= code_for('array_comprehensions') %>
<p> <p>
If you're not iterating over an actual array, you can use a range to If you know the start and end of your loop, or would like to step through
specify the start and end of an array comprehension: in fixed-size increments, you can use a range to specify the start and
<tt>coundown(i) for i in [10..1].</tt> end of your comprehension:
</p> </p>
<%= code_for('range_comprehensions') %>
<p>
Comprehensions can also be used to iterate over the values and keys in
an object:
</p>
<%= code_for('object_comprehensions', 'ages.join(", ")') %>
<p id="slice"> <p id="slice_splice">
<b class="header">Slicing Arrays with Ranges</b> <b class="header">Array Slicing and Splicing with Ranges</b>
CoffeeScript borrows Ruby's CoffeeScript borrows Ruby's
<a href="http://ruby-doc.org/core/classes/Range.html">range syntax</a> <a href="http://ruby-doc.org/core/classes/Range.html">range syntax</a>
for extracting slices of arrays. With two dots (<tt>3..5</tt>), the range for extracting slices of arrays. With two dots (<tt>3..5</tt>), the range
@ -393,6 +423,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
a range that excludes the end. a range that excludes the end.
</p> </p>
<%= code_for('slices', 'numbers_copy') %> <%= code_for('slices', 'numbers_copy') %>
<p>
The same syntax can be used with assignment to replace a segment of an
array with new values (to splice it).
</p>
<%= code_for('splices', 'numbers') %>
<p id="inheritance"> <p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b> <b class="header">Inheritance, and Calling Super from a Subclass</b>

View file

@ -1,5 +1,5 @@
(function(){ (function(){
var __a, __b, __c, __d, __e, __f, food, i, lunch, row; var __a, __b, __c, __d, __e, __f, __g, __h, __i, __j, food, lunch, roid, roid2;
// Eat lunch. // Eat lunch.
lunch = (function() { lunch = (function() {
__a = ['toast', 'cheese', 'wine']; __a = ['toast', 'cheese', 'wine'];
@ -7,18 +7,28 @@
for (__b in __a) { for (__b in __a) {
if (__a.hasOwnProperty(__b)) { if (__a.hasOwnProperty(__b)) {
food = __a[__b]; food = __a[__b];
__d = this.eat(food); __d = eat(food);
__c.push(__d); __c.push(__d);
} }
} }
return __c; return __c;
})(); })();
// Zebra-stripe a table. // Naive collision detection.
__e = table; __e = asteroids;
for (i in __e) { for (__f in __e) {
if (__e.hasOwnProperty(i)) { if (__e.hasOwnProperty(__f)) {
row = __e[i]; roid = __e[__f];
i % 2 === 0 ? highlight(row) : null; __h = asteroids;
for (__i in __h) {
if (__h.hasOwnProperty(__i)) {
roid2 = __h[__i];
if (roid !== roid2) {
if (roid.overlaps(roid2)) {
roid.explode();
}
}
}
}
} }
} }
})(); })();

View file

@ -0,0 +1,6 @@
(function(){
var solipsism;
if ((typeof mind !== 'undefined' && mind !== null) && !(typeof world !== 'undefined' && world !== null)) {
solipsism = true;
}
})();

View file

@ -0,0 +1,16 @@
(function(){
var __a, __b, __c, globals, name, property;
// The first ten global properties.
globals = ((function() {
__a = window;
__b = [];
for (name in __a) {
if (__a.hasOwnProperty(name)) {
property = __a[name];
__c = name;
__b.push(__c);
}
}
return __b;
})()).slice(0, 10);
})();

View file

@ -0,0 +1,9 @@
(function(){
alert((function() {
try {
return nonexistent / undefined;
} catch (error) {
return "The error is: " + error;
}
})());
})();

View file

@ -0,0 +1,20 @@
(function(){
var __a, __b, __c, age, ages, child, years_old;
years_old = {
max: 10,
ida: 9,
tim: 11
};
ages = (function() {
__a = years_old;
__b = [];
for (child in __a) {
if (__a.hasOwnProperty(child)) {
age = __a[child];
__c = child + " is " + age;
__b.push(__c);
}
}
return __b;
})();
})();

View file

@ -1,9 +1,10 @@
(function(){ (function(){
var ages, song; var ages, matrix, song;
song = ["do", "re", "mi", "fa", "so"]; song = ["do", "re", "mi", "fa", "so"];
ages = { ages = {
max: 10, max: 10,
ida: 9, ida: 9,
tim: 11 tim: 11
}; };
matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0];
})(); })();

View file

@ -0,0 +1,9 @@
(function(){
var __a, __b, __c, __d, __e, dozen_eggs, i;
__d = 0;
__e = eggs.length;
for (__c=0, i=__d; (__d <= __e ? i < __e : i > __e); (__d <= __e ? i += 12 : i -= 12), __c++) {
dozen_eggs = eggs.slice(i, i + 12);
deliver(new egg_carton(dozen));
}
})();

View file

@ -3,8 +3,8 @@
num = 1; num = 1;
change_numbers = function change_numbers() { change_numbers = function change_numbers() {
var new_num; var new_num;
num = 2; new_num = -1;
return new_num = 3; return num = 10;
}; };
new_num = change_numbers(); new_num = change_numbers();
})(); })();

View file

@ -0,0 +1,5 @@
(function(){
var numbers;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
numbers.splice.apply(numbers, [3, 6 - 3 + 1].concat([-3, -4, -5, -6]));
})();

View file

@ -47,17 +47,18 @@
<p> <p>
<a href="#overview">Mini Overview</a><br /> <a href="#overview">Mini Overview</a><br />
<a href="#installation">Installation and Usage</a><br /> <a href="#installation">Installation and Usage</a><br />
<a href="#punctuation">Punctuation Primer</a><br /> <a href="#whitespace">Significant Whitespace</a><br />
<a href="#functions">Functions and Invocation</a><br /> <a href="#functions">Functions and Invocation</a><br />
<a href="#assignment">Assignment</a><br /> <a href="#assignment">Assignment</a><br />
<a href="#objects_and_arrays">Objects and Arrays</a><br /> <a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br /> <a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br /> <a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#existence">The Existence Operator</a><br />
<a href="#expressions">Everything is an Expression</a><br /> <a href="#expressions">Everything is an Expression</a><br />
<a href="#aliases">Aliases</a><br /> <a href="#aliases">Aliases</a><br />
<a href="#while">While Loops</a><br /> <a href="#while">While Loops</a><br />
<a href="#array_comprehensions">Array Comprehensions</a><br /> <a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a><br />
<a href="#slice">Slicing Arrays with Ranges</a><br /> <a href="#slice_splice">Array Slicing and Splicing with Ranges</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br /> <a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br /> <a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/When/Else</a><br /> <a href="#switch">Switch/When/Else</a><br />
@ -290,22 +291,22 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</i> </i>
</p> </p>
<p id="punctuation"> <p id="whitespace">
<b class="header">Punctuation Primer</b> <b class="header">Significant Whitespace</b>
You don't need to use semicolons <tt>;</tt> to terminate expressions, ending CoffeeScript uses Python-style significant whitespace: You don't need to
the line will do just as well. All other whitespace is use semicolons <tt>;</tt> to terminate expressions, ending
not significant. Instead of using curly braces <tt>{ }</tt> the line will do just as well. Semicolons can still be used to fit
to delimit a block of code, use a period <tt>.</tt> to mark the end of a multiple expressions onto a single line. Instead of using curly braces
block, for <tt>{ }</tt> to delimit a block of code (like <a href="#functions">functions</a>,
<a href="#functions">functions</a>,
<a href="#conditionals">if-statements</a>, <a href="#conditionals">if-statements</a>,
<a href="#switch">switch</a>, and <a href="#try">try/catch</a>. <a href="#switch">switch</a>, and <a href="#try">try/catch</a>),
use indentation.
</p> </p>
<p id="functions"> <p id="functions">
<b class="header">Functions and Invocation</b> <b class="header">Functions and Invocation</b>
Functions are defined by a list of parameters, an arrow, and the Functions are defined by a list of parameters, an arrow, and the
function body. The empty function looks like this: <tt>=>.</tt> function body. The empty function looks like this: <tt>=></tt>
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">square</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=&gt;</span> x <span class="Keyword">*</span> x <div class='code'><pre class="idle"><span class="FunctionName">square</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=&gt;</span> x <span class="Keyword">*</span> x
<span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=&gt;</span> square(x) <span class="Keyword">*</span> x <span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=&gt;</span> square(x) <span class="Keyword">*</span> x
@ -341,8 +342,8 @@ greeting = "Hello CoffeeScript";
difficulty = 0.5; difficulty = 0.5;
;alert(greeting);'>run: greeting</button><br class='clear' /></div> ;alert(greeting);'>run: greeting</button><br class='clear' /></div>
<p> <p>
Declarations of new variables are pushed up to the top of the current scope, Declarations of new variables are pushed up to the top of the nearest
so that assignments may always be used within expressions. lexical scope, so that assignment may always be used within expressions.
</p> </p>
<p id="objects_and_arrays"> <p id="objects_and_arrays">
@ -350,28 +351,38 @@ difficulty = 0.5;
Object and Array literals look very similar to their JavaScript cousins. Object and Array literals look very similar to their JavaScript cousins.
When you spread out each assignment on a separate line, the commas are When you spread out each assignment on a separate line, the commas are
optional. In this way, assigning object properties looks the same as optional. In this way, assigning object properties looks the same as
assigning local variables. assigning local variables, and can be moved around freely. You can mix
and match the two styles.
</p> </p>
<div class='code'><pre class="idle">song<span class="Keyword">:</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>] <div class='code'><pre class="idle">song<span class="Keyword">:</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>]
ages<span class="Keyword">:</span> { ages<span class="Keyword">:</span> {
max<span class="Keyword">:</span> <span class="Number">10</span> max<span class="Keyword">:</span> <span class="Number">10</span>
ida<span class="Keyword">:</span> <span class="Number">9</span> ida<span class="Keyword">:</span> <span class="Number">9</span>
tim<span class="Keyword">:</span> <span class="Number">11</span> tim<span class="Keyword">:</span> <span class="Number">11</span>
} }
</pre><pre class="idle"><span class="Storage">var</span> ages, song;
matrix<span class="Keyword">:</span> [
<span class="Number">1</span>, <span class="Number">0</span>, <span class="Number">1</span>
<span class="Number">0</span>, <span class="Number">0</span>, <span class="Number">1</span>
<span class="Number">1</span>, <span class="Number">1</span>, <span class="Number">0</span>
]
</pre><pre class="idle"><span class="Storage">var</span> ages, matrix, song;
song <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>]; song <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>];
ages <span class="Keyword">=</span> { ages <span class="Keyword">=</span> {
max: <span class="Number">10</span>, max: <span class="Number">10</span>,
ida: <span class="Number">9</span>, ida: <span class="Number">9</span>,
tim: <span class="Number">11</span> tim: <span class="Number">11</span>
}; };
</pre><button onclick='javascript: var ages, song; matrix <span class="Keyword">=</span> [<span class="Number">1</span>, <span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">0</span>, <span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">1</span>, <span class="Number">1</span>, <span class="Number">0</span>];
</pre><button onclick='javascript: var ages, matrix, song;
song = ["do", "re", "mi", "fa", "so"]; song = ["do", "re", "mi", "fa", "so"];
ages = { ages = {
max: 10, max: 10,
ida: 9, ida: 9,
tim: 11 tim: 11
}; };
matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0];
;alert(song.join(","));'>run: song.join(",")</button><br class='clear' /></div> ;alert(song.join(","));'>run: song.join(",")</button><br class='clear' /></div>
<p id="lexical_scope"> <p id="lexical_scope">
@ -382,46 +393,50 @@ ages = {
</p> </p>
<div class='code'><pre class="idle">num<span class="Keyword">:</span> <span class="Number">1</span> <div class='code'><pre class="idle">num<span class="Keyword">:</span> <span class="Number">1</span>
<span class="FunctionName">change_numbers</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span> <span class="FunctionName">change_numbers</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
num<span class="Keyword">:</span> <span class="Number">2</span> new_num<span class="Keyword">:</span> <span class="Keyword">-</span><span class="Number">1</span>
new_num<span class="Keyword">:</span> <span class="Number">3</span> num<span class="Keyword">:</span> <span class="Number">10</span>
new_num<span class="Keyword">:</span> change_numbers() new_num<span class="Keyword">:</span> change_numbers()
</pre><pre class="idle"><span class="Storage">var</span> change_numbers, new_num, num; </pre><pre class="idle"><span class="Storage">var</span> change_numbers, new_num, num;
num <span class="Keyword">=</span> <span class="Number">1</span>; num <span class="Keyword">=</span> <span class="Number">1</span>;
change_numbers <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">change_numbers</span>() { change_numbers <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">change_numbers</span>() {
<span class="Storage">var</span> new_num; <span class="Storage">var</span> new_num;
num <span class="Keyword">=</span> <span class="Number">2</span>; new_num <span class="Keyword">=</span> <span class="Keyword">-</span><span class="Number">1</span>;
<span class="Keyword">return</span> new_num <span class="Keyword">=</span> <span class="Number">3</span>; <span class="Keyword">return</span> num <span class="Keyword">=</span> <span class="Number">10</span>;
}; };
new_num <span class="Keyword">=</span> change_numbers(); new_num <span class="Keyword">=</span> change_numbers();
</pre><button onclick='javascript: var change_numbers, new_num, num; </pre><button onclick='javascript: var change_numbers, new_num, num;
num = 1; num = 1;
change_numbers = function change_numbers() { change_numbers = function change_numbers() {
var new_num; var new_num;
num = 2; new_num = -1;
return new_num = 3; return num = 10;
}; };
new_num = change_numbers(); new_num = change_numbers();
;alert(new_num);'>run: new_num</button><br class='clear' /></div> ;alert(new_num);'>run: new_num</button><br class='clear' /></div>
<p> <p>
Notice how the variables are declared with <tt>var</tt> the first time Notice how the all of the variable declarations have been pushed up to
they appear. The second reference of <b>num</b>, within the function, the top of the closest scope, the first time they appear.
is not redeclared because <b>num</b> is still in scope. As opposed <b>num</b> is not redeclared within the inner function, because it's
to the second occurrence of <b>new_num</b>, in the last line. already in scope; the <b>new_num</b> within the function, on the other hand,
should not be able to change the value of the external variable of the same name, and
therefore has a declaration of its own.
</p> </p>
<p> <p>
Although suppressed within this documentation for clarity, all Although suppressed within this documentation for clarity, all
CoffeeScript output is wrapped in an anonymous function: CoffeeScript output is wrapped in an anonymous function:
<tt>(function(){ ... })();</tt> This safety wrapper, combined with the <tt>(function(){ ... })();</tt> This safety wrapper, combined with the
automatic generation of the <tt>var</tt> keyword, make it exceedingly difficult automatic generation of the <tt>var</tt> keyword, make it exceedingly difficult
to pollute the global namespace by accident. to pollute the global namespace by accident. If you'd like to create
global variables, attach them as properties on <b>window</b>,
or on the <b>exports</b> object in CommonJS.
</p> </p>
<p id="conditionals"> <p id="conditionals">
<b class="header">Conditionals, Ternaries, and Conditional Assignment</b> <b class="header">Conditionals, Ternaries, and Conditional Assignment</b>
<b>If/else</b> statements can be written without the use of parentheses and <b>If/else</b> statements can be written without the use of parentheses and
curly brackets. As with functions and other block expressions, conditionals curly brackets. As with functions and other block expressions,
are closed with periods. No period is necessary when using the single-line multi-line conditionals are delimited by indentation. There's also a handy
postfix form, with the <tt>if</tt> at the end. postfix form, with the <tt>if</tt> or <tt>unless</tt> at the end.
</p> </p>
<p> <p>
CoffeeScript will compile <b>if</b> statements using the ternary operator CoffeeScript will compile <b>if</b> statements using the ternary operator
@ -448,12 +463,27 @@ date <span class="Keyword">=</span> friday ? sue : jill;
expensive <span class="Keyword">=</span> expensive <span class="Keyword">||</span> do_the_math(); expensive <span class="Keyword">=</span> expensive <span class="Keyword">||</span> do_the_math();
</pre><br class='clear' /></div> </pre><br class='clear' /></div>
<p> <p>
The conditional assignment operators are available: <tt>||=</tt>, The conditional assignment operators are included: <tt>||=</tt>,
which only assigns a value to a variable if the variable's current value which only assigns a value to a variable if the variable's current value
is falsy, and <tt>&amp;&amp;=</tt>, which only replaces the value of is falsy, and <tt>&amp;&amp;=</tt>, which only replaces the value of
truthy variables. truthy variables.
</p> </p>
<p id="existence">
<b class="header">The Existence Operator</b>
It's a little difficult to check for the existence of a variable in
JavaScript. <tt>if (variable) ...</tt> comes close, but fails for zero,
the empty string, and false. The existence operator <tt>?</tt> returns true unless
a variable is <b>null</b> or <b>undefined</b>, which makes it analogous
to <b>nil?</b> in Ruby.
</p>
<div class='code'><pre class="idle">solipsism<span class="Keyword">:</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> mind<span class="Keyword">?</span> <span class="Keyword">and</span> <span class="Keyword">not</span> world<span class="Keyword">?</span>
</pre><pre class="idle"><span class="Storage">var</span> solipsism;
<span class="Keyword">if</span> ((<span class="Keyword">typeof</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">'</span>undefined<span class="String">'</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> <span class="Keyword">!</span>(<span class="Keyword">typeof</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">'</span>undefined<span class="String">'</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>)) {
solipsism <span class="Keyword">=</span> <span class="BuiltInConstant">true</span>;
}
</pre><br class='clear' /></div>
<p id="expressions"> <p id="expressions">
<b class="header">Everything is an Expression (at least, as much as possible)</b> <b class="header">Everything is an Expression (at least, as much as possible)</b>
You might have noticed how even though we don't add return statements You might have noticed how even though we don't add return statements
@ -496,12 +526,8 @@ grade = function grade(student) {
eldest = 24 > 21 ? "Liz" : "Ike"; eldest = 24 > 21 ? "Liz" : "Ike";
;alert(eldest);'>run: eldest</button><br class='clear' /></div> ;alert(eldest);'>run: eldest</button><br class='clear' /></div>
<p> <p>
The same mechanism is used to push down assignment through <b>switch</b> Because variable declarations occur at the top of scope, assignment can
statements, and <b>if-elses</b> (although the ternary operator is preferred). be used within expressions, even for variables that haven't been seen before:
Another part of manipulating assignment statements is
CoffeeScript's declaration of new variables at the top of the
current scope. This allows assignment to be used as a piece of an
expression.
</p> </p>
<div class='code'><pre class="idle">six<span class="Keyword">:</span> (one<span class="Keyword">:</span> <span class="Number">1</span>) <span class="Keyword">+</span> (two<span class="Keyword">:</span> <span class="Number">2</span>) <span class="Keyword">+</span> (three<span class="Keyword">:</span> <span class="Number">3</span>) <div class='code'><pre class="idle">six<span class="Keyword">:</span> (one<span class="Keyword">:</span> <span class="Number">1</span>) <span class="Keyword">+</span> (two<span class="Keyword">:</span> <span class="Number">2</span>) <span class="Keyword">+</span> (three<span class="Keyword">:</span> <span class="Number">3</span>)
</pre><pre class="idle"><span class="Storage">var</span> one, six, three, two; </pre><pre class="idle"><span class="Storage">var</span> one, six, three, two;
@ -509,6 +535,69 @@ six <span class="Keyword">=</span> (one <span class="Keyword">=</span> <span cla
</pre><button onclick='javascript: var one, six, three, two; </pre><button onclick='javascript: var one, six, three, two;
six = (one = 1) + (two = 2) + (three = 3); six = (one = 1) + (two = 2) + (three = 3);
;alert(six);'>run: six</button><br class='clear' /></div> ;alert(six);'>run: six</button><br class='clear' /></div>
<p>
Things that would otherwise be statements in JavaScript, when used
as part of an expression in CoffeeScript, are converted into expressions
by wrapping them in a closure. This lets you do useful things, like assign
the result of a comprehension to a variable:
</p>
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> The first ten global properties.</span>
globals<span class="Keyword">:</span> (name <span class="Keyword">for</span> property, name <span class="Keyword">in</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, globals, name, property;
<span class="Comment"><span class="Comment">//</span> The first ten global properties.</span>
globals <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
__a <span class="Keyword">=</span> <span class="LibraryClassType">window</span>;
__b <span class="Keyword">=</span> [];
<span class="Keyword">for</span> (name <span class="Keyword">in</span> __a) {
<span class="Keyword">if</span> (__a.hasOwnProperty(name)) {
property <span class="Keyword">=</span> __a[name];
__c <span class="Keyword">=</span> name;
__b.<span class="LibraryFunction">push</span>(__c);
}
}
<span class="Keyword">return</span> __b;
})()).<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
</pre><button onclick='javascript: var __a, __b, __c, globals, name, property;
// The first ten global properties.
globals = ((function() {
__a = window;
__b = [];
for (name in __a) {
if (__a.hasOwnProperty(name)) {
property = __a[name];
__c = name;
__b.push(__c);
}
}
return __b;
})()).slice(0, 10);
;alert(globals);'>run: globals</button><br class='clear' /></div>
<p>
As well as silly things, like passing a <b>try/catch</b> statement directly
into a function call:
</p>
<div class='code'><pre class="idle">alert(
<span class="Keyword">try</span>
nonexistent <span class="Keyword">/</span> <span class="BuiltInConstant">undefined</span>
<span class="Keyword">catch</span> error
<span class="String"><span class="String">&quot;</span>The error is: <span class="String">&quot;</span></span> <span class="Keyword">+</span> error
)
</pre><pre class="idle"><span class="LibraryFunction">alert</span>((<span class="Storage">function</span>() {
<span class="Keyword">try</span> {
<span class="Keyword">return</span> nonexistent / undefined;
} <span class="Keyword">catch</span> (error) {
<span class="Keyword">return</span> <span class="String"><span class="String">&quot;</span>The error is: <span class="String">&quot;</span></span> <span class="Keyword">+</span> error;
}
})());
</pre><button onclick='javascript: alert((function() {
try {
return nonexistent / undefined;
} catch (error) {
return "The error is: " + error;
}
})());
;'>run</button><br class='clear' /></div>
<p id="aliases"> <p id="aliases">
<b class="header">Aliases</b> <b class="header">Aliases</b>
@ -582,8 +671,8 @@ car.speed <span class="Keyword">&lt;</span> speed_limit ? accelerate() : <span c
<b>each</b> (<b>forEach</b>) style iterators, or... <b>each</b> (<b>forEach</b>) style iterators, or...
</p> </p>
<p id="array_comprehensions"> <p id="comprehensions">
<b class="header">Array Comprehensions</b> <b class="header">Comprehensions (Arrays, Objects, and Ranges)</b>
For your looping needs, CoffeeScript provides array comprehensions For your looping needs, CoffeeScript provides array comprehensions
similar to Python's. They replace (and compile into) <b>for</b> loops, with similar to Python's. They replace (and compile into) <b>for</b> loops, with
optional guard clauses and the value of the current array index. optional guard clauses and the value of the current array index.
@ -592,11 +681,13 @@ car.speed <span class="Keyword">&lt;</span> speed_limit ? accelerate() : <span c
would use a loop, <b>each</b>/<b>forEach</b>, <b>map</b>, or <b>select</b>/<b>filter</b>. would use a loop, <b>each</b>/<b>forEach</b>, <b>map</b>, or <b>select</b>/<b>filter</b>.
</p> </p>
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> Eat lunch.</span> <div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> Eat lunch.</span>
lunch<span class="Keyword">:</span> <span class="Variable">this</span>.eat(food) <span class="Keyword">for</span> food <span class="Keyword">in</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>] lunch<span class="Keyword">:</span> eat(food) <span class="Keyword">for</span> food <span class="Keyword">in</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>]
<span class="Comment"><span class="Comment">#</span> Zebra-stripe a table.</span> <span class="Comment"><span class="Comment">#</span> Naive collision detection.</span>
highlight(row) <span class="Keyword">for</span> row, i <span class="Keyword">in</span> table <span class="Keyword">when</span> i <span class="Keyword">%</span> <span class="Number">2</span> <span class="Keyword">is</span> <span class="Number">0</span> <span class="Keyword">for</span> roid <span class="Keyword">in</span> asteroids
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, __e, __f, food, i, lunch, row; <span class="Keyword">for</span> roid2 <span class="Keyword">in</span> asteroids <span class="Keyword">when</span> roid <span class="Keyword">isnt</span> roid2
roid.explode() <span class="Keyword">if</span> roid.overlaps(roid2)
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, __e, __f, __g, __h, __i, __j, food, lunch, roid, roid2;
<span class="Comment"><span class="Comment">//</span> Eat lunch.</span> <span class="Comment"><span class="Comment">//</span> Eat lunch.</span>
lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() { lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
__a <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>]; __a <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
@ -604,29 +695,94 @@ lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
<span class="Keyword">for</span> (__b <span class="Keyword">in</span> __a) { <span class="Keyword">for</span> (__b <span class="Keyword">in</span> __a) {
<span class="Keyword">if</span> (__a.hasOwnProperty(__b)) { <span class="Keyword">if</span> (__a.hasOwnProperty(__b)) {
food <span class="Keyword">=</span> __a[__b]; food <span class="Keyword">=</span> __a[__b];
__d <span class="Keyword">=</span> <span class="Variable">this</span>.eat(food); __d <span class="Keyword">=</span> eat(food);
__c.<span class="LibraryFunction">push</span>(__d); __c.<span class="LibraryFunction">push</span>(__d);
} }
} }
<span class="Keyword">return</span> __c; <span class="Keyword">return</span> __c;
})(); })();
<span class="Comment"><span class="Comment">//</span> Zebra-stripe a table.</span> <span class="Comment"><span class="Comment">//</span> Naive collision detection.</span>
__e <span class="Keyword">=</span> table; __e <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> (i <span class="Keyword">in</span> __e) { <span class="Keyword">for</span> (__f <span class="Keyword">in</span> __e) {
<span class="Keyword">if</span> (__e.hasOwnProperty(i)) { <span class="Keyword">if</span> (__e.hasOwnProperty(__f)) {
row <span class="Keyword">=</span> __e[i]; roid <span class="Keyword">=</span> __e[__f];
i <span class="Keyword">%</span> <span class="Number">2</span> <span class="Keyword">===</span> <span class="Number">0</span> ? highlight(row) : <span class="BuiltInConstant">null</span>; __h <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> (__i <span class="Keyword">in</span> __h) {
<span class="Keyword">if</span> (__h.hasOwnProperty(__i)) {
roid2 <span class="Keyword">=</span> __h[__i];
<span class="Keyword">if</span> (roid <span class="Keyword">!</span><span class="Keyword">==</span> roid2) {
<span class="Keyword">if</span> (roid.overlaps(roid2)) {
roid.explode();
}
}
}
}
} }
} }
</pre><br class='clear' /></div> </pre><br class='clear' /></div>
<p> <p>
If you're not iterating over an actual array, you can use a range to If you know the start and end of your loop, or would like to step through
specify the start and end of an array comprehension: in fixed-size increments, you can use a range to specify the start and
<tt>coundown(i) for i in [10..1].</tt> end of your comprehension:
</p> </p>
<div class='code'><pre class="idle"><span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span>
dozen_eggs<span class="Keyword">:</span> eggs[i...i<span class="Keyword">+</span><span class="Number">12</span>]
deliver(<span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen))
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, __e, dozen_eggs, i;
__d <span class="Keyword">=</span> <span class="Number">0</span>;
__e <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
<span class="Keyword">for</span> (__c<span class="Keyword">=</span><span class="Number">0</span>, i<span class="Keyword">=</span>__d; (__d <span class="Keyword">&lt;=</span> __e ? i <span class="Keyword">&lt;</span> __e : i <span class="Keyword">&gt;</span> __e); (__d <span class="Keyword">&lt;=</span> __e ? i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span> : i <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">12</span>), __c<span class="Keyword">++</span>) {
dozen_eggs <span class="Keyword">=</span> eggs.<span class="LibraryFunction">slice</span>(i, i <span class="Keyword">+</span> <span class="Number">12</span>);
deliver(<span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen));
}
</pre><br class='clear' /></div>
<p>
Comprehensions can also be used to iterate over the values and keys in
an object:
</p>
<div class='code'><pre class="idle">years_old<span class="Keyword">:</span> {max<span class="Keyword">:</span> <span class="Number">10</span>, ida<span class="Keyword">:</span> <span class="Number">9</span>, tim<span class="Keyword">:</span> <span class="Number">11</span>}
<p id="slice"> ages<span class="Keyword">:</span> child <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> is <span class="String">&quot;</span></span> <span class="Keyword">+</span> age <span class="Keyword">for</span> age, child <span class="Keyword">in</span> years_old
<b class="header">Slicing Arrays with Ranges</b> </pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, age, ages, child, years_old;
years_old <span class="Keyword">=</span> {
max: <span class="Number">10</span>,
ida: <span class="Number">9</span>,
tim: <span class="Number">11</span>
};
ages <span class="Keyword">=</span> (<span class="Storage">function</span>() {
__a <span class="Keyword">=</span> years_old;
__b <span class="Keyword">=</span> [];
<span class="Keyword">for</span> (child <span class="Keyword">in</span> __a) {
<span class="Keyword">if</span> (__a.hasOwnProperty(child)) {
age <span class="Keyword">=</span> __a[child];
__c <span class="Keyword">=</span> child <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> is <span class="String">&quot;</span></span> <span class="Keyword">+</span> age;
__b.<span class="LibraryFunction">push</span>(__c);
}
}
<span class="Keyword">return</span> __b;
})();
</pre><button onclick='javascript: var __a, __b, __c, age, ages, child, years_old;
years_old = {
max: 10,
ida: 9,
tim: 11
};
ages = (function() {
__a = years_old;
__b = [];
for (child in __a) {
if (__a.hasOwnProperty(child)) {
age = __a[child];
__c = child + " is " + age;
__b.push(__c);
}
}
return __b;
})();
;alert(ages.join(", "));'>run: ages.join(", ")</button><br class='clear' /></div>
<p id="slice_splice">
<b class="header">Array Slicing and Splicing with Ranges</b>
CoffeeScript borrows Ruby's CoffeeScript borrows Ruby's
<a href="http://ruby-doc.org/core/classes/Range.html">range syntax</a> <a href="http://ruby-doc.org/core/classes/Range.html">range syntax</a>
for extracting slices of arrays. With two dots (<tt>3..5</tt>), the range for extracting slices of arrays. With two dots (<tt>3..5</tt>), the range
@ -649,6 +805,22 @@ numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
three_to_six = numbers.slice(3, 6 + 1); three_to_six = numbers.slice(3, 6 + 1);
numbers_copy = numbers.slice(0, numbers.length); numbers_copy = numbers.slice(0, numbers.length);
;alert(numbers_copy);'>run: numbers_copy</button><br class='clear' /></div> ;alert(numbers_copy);'>run: numbers_copy</button><br class='clear' /></div>
<p>
The same syntax can be used with assignment to replace a segment of an
array with new values (to splice it).
</p>
<div class='code'><pre class="idle">numbers<span class="Keyword">:</span> [<span class="Number">0</span>, <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>]
numbers[<span class="Number">3</span>..<span class="Number">6</span>]<span class="Keyword">:</span> [<span class="Keyword">-</span><span class="Number">3</span>, <span class="Keyword">-</span><span class="Number">4</span>, <span class="Keyword">-</span><span class="Number">5</span>, <span class="Keyword">-</span><span class="Number">6</span>]
</pre><pre class="idle"><span class="Storage">var</span> numbers;
numbers <span class="Keyword">=</span> [<span class="Number">0</span>, <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>];
numbers.splice.<span class="LibraryFunction">apply</span>(numbers, [<span class="Number">3</span>, <span class="Number">6</span> <span class="Keyword">-</span> <span class="Number">3</span> <span class="Keyword">+</span> <span class="Number">1</span>].<span class="LibraryFunction">concat</span>([<span class="Keyword">-</span><span class="Number">3</span>, <span class="Keyword">-</span><span class="Number">4</span>, <span class="Keyword">-</span><span class="Number">5</span>, <span class="Keyword">-</span><span class="Number">6</span>]));
</pre><button onclick='javascript: var numbers;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
numbers.splice.apply(numbers, [3, 6 - 3 + 1].concat([-3, -4, -5, -6]));
;alert(numbers);'>run: numbers</button><br class='clear' /></div>
<p id="inheritance"> <p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b> <b class="header">Inheritance, and Calling Super from a Subclass</b>

View file

@ -19,7 +19,8 @@ token INDENT OUTDENT
# Declare order of operations. # Declare order of operations.
prechigh prechigh
nonassoc UMINUS PARAM_SPLAT SPLAT NOT '!' '!!' '~' '++' '--' '?' left '?'
nonassoc UMINUS PARAM_SPLAT SPLAT NOT '!' '!!' '~' '++' '--'
left '*' '/' '%' left '*' '/' '%'
left '+' '-' left '+' '-'
left '<<' '>>' '>>>' left '<<' '>>' '>>>'