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

* Docs: named functions and function declarations * No more prototypal `extends`; update docs and example * More comprehensive documentation of the existential operator; closes #1631 * Better document operators, including `from` * No fat arrow class methods anymore * Destructuring shouldn’t say that default values are applied in case of undefined or null * Spinoff generator and async functions into their own sections; reorder things so that the sections on functions come just before classes, and destructuring goes next to the operators (which discuss assignment) * Rewrite “CoffeeScript 2” section, making it less practical and more explanatory; move practical info into “Usage” * Update “Variable Scoping and Lexical Safety” section to remove incorrect reference to Ruby (fixes #2360), add missing details about the safety wrapper, add note about `let`/`const`. * Updated browser compiler * Updated docs * Rewrite Literate CoffeeScript breaking changes * Split apart the “Breaking Changes” and “Unsupported Features” sections into separate sidebar items and files * Add example of `not in`, closes #3281 * Fix words in bold that should be in backticks * Consolidate some breaking changes sections * Add Node API documentation; closes #3551 * Move the chaining documentation out of the changelog into its own section
47 lines
2.8 KiB
Markdown
47 lines
2.8 KiB
Markdown
## Loops and Comprehensions
|
||
|
||
Most of the loops you’ll write in CoffeeScript will be **comprehensions** over arrays, objects, and ranges. Comprehensions replace (and compile into) `for` 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.
|
||
|
||
```
|
||
codeFor('array_comprehensions')
|
||
```
|
||
|
||
Comprehensions should be able to handle most places where you otherwise would use a loop, `each`/`forEach`, `map`, or `select`/`filter`, for example:<br>
|
||
`shortNames = (name for name in list when name.length < 5)`<br>
|
||
If you know the start and end of your loop, or would like to step through in fixed-size increments, you can use a range to specify the start and end of your comprehension.
|
||
|
||
```
|
||
codeFor('range_comprehensions', 'countdown')
|
||
```
|
||
|
||
Note how because we are assigning the value of the comprehensions to a variable in the example above, CoffeeScript is collecting the result of each iteration into an array. Sometimes functions end with loops that are intended to run only for their side-effects. Be careful that you’re not accidentally returning the results of the comprehension in these cases, by adding a meaningful return value — like `true` — or `null`, to the bottom of your function.
|
||
|
||
To step through a range comprehension in fixed-size chunks, use `by`, for example:
|
||
`evens = (x for x in [0..10] by 2)`
|
||
|
||
If you don’t need the current iteration value you may omit it:
|
||
`browser.closeCurrentTab() for [0...count]`
|
||
|
||
Comprehensions can also be used to iterate over the keys and values in an object. Use `of` to signal comprehension over the properties of an object instead of the values in an array.
|
||
|
||
```
|
||
codeFor('object_comprehensions', 'ages.join(", ")')
|
||
```
|
||
|
||
If you would like to iterate over just the keys that are defined on the object itself, by adding a `hasOwnProperty` check to avoid properties that may be inherited from the prototype, use `for own key, value of object`.
|
||
|
||
To iterate a generator function, use `from`. See [Generator Functions](#generator-iteration).
|
||
|
||
The only low-level loop that CoffeeScript provides is the `while` loop. The main difference from JavaScript is that the `while` loop can be used as an expression, returning an array containing the result of each iteration through the loop.
|
||
|
||
```
|
||
codeFor('while', 'lyrics.join("\\n")')
|
||
```
|
||
|
||
For readability, the `until` keyword is equivalent to `while not`, and the `loop` keyword is equivalent to `while true`.
|
||
|
||
When using a JavaScript loop to generate functions, it’s common to insert a closure wrapper in order to ensure that loop variables are closed over, and all the generated functions don’t just share the final values. CoffeeScript provides the `do` keyword, which immediately invokes a passed function, forwarding any arguments.
|
||
|
||
```
|
||
codeFor('do')
|
||
```
|