CoffeeScript: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
 
(не показаны 22 промежуточные версии 15 участников)
Строка 1: Строка 1:
{{Язык программирования
{{Язык программирования
|name = CoffeeScript
| name = CoffeeScript
|logo = CoffeeScript.png
| logo = CoffeeScript-logo.svg
|semantics =
| semantics =
|paradigm = [[Мультипарадигмальный язык программирования|мультипарадигмальный]]:
| paradigm = [[Мультипарадигмальный язык программирования|мультипарадигмальный]]:
[[Объектно-ориентированное программирование|объектно-ориентированный]], [[Императивное программирование|императивный]], [[Функциональное программирование|функциональный]], [[Аспектно-ориентированное программирование|аспектно-ориентированный]], [[Прототипное программирование|прототипный]]
[[Объектно-ориентированное программирование|объектно-ориентированный]], [[Императивное программирование|императивный]], [[Функциональное программирование|функциональный]], [[Аспектно-ориентированное программирование|аспектно-ориентированный]], [[Прототипное программирование|прототипный]]
|class =
| class =
| последняя версия = 2.7.0<ref>{{Cite news|title=2.7.0|url=https://github.com/jashkenas/coffeescript/releases/tag/2.7.0|accessdate=2022-06-23|archivedate=2022-06-23|archiveurl=https://web.archive.org/web/20220623172110/https://github.com/jashkenas/coffeescript/releases/tag/2.7.0}}</ref>
|latest_preview_version =
| дата выпуска последней версии = {{start date and age|2022|04|24}}
|latest_preview_date =
| latest_preview_version =
|typing =
| latest_preview_date =
|implementations =
| typing =
|dialects =
| implementations =
|influenced_by = [[JavaScript]], [[Python]], [[Ruby]], [[Haskell]], [[Erlang]]
| dialects =
|influenced = [[MoonScript]], [[LiveScript]]
| influenced_by = [[JavaScript]], [[Python]], [[Ruby]], [[Haskell]], [[Erlang]]
|designer = [[Джереми Ашкенас]]}}
| influenced = [[MoonScript]], [[LiveScript]]
| designer = [[Джереми Ашкенас]]
}}


'''CoffeeScript''' ({{IPA|[’kɔ:fɪ skrɪpt]}}; ''кофи скрипт'') — язык программирования, [[Транслятор|транслируемый]] в [[JavaScript]]. CoffeeScript добавляет [[синтаксический сахар]] в духе [[Ruby]], [[Python]], [[Haskell]] и [[Erlang]] для того, чтобы улучшить читаемость кода и уменьшить его размер.
'''CoffeeScript''' ({{IPA|[’kɔ:fɪ skrɪpt]}}; ''кофи скрипт'') — язык программирования, [[Транслятор|транслируемый]] в [[JavaScript]]. CoffeeScript добавляет [[синтаксический сахар]] в духе [[Ruby]], [[Python]], [[Haskell]] и [[Erlang]] для того, чтобы улучшить читаемость кода и уменьшить его размер.
CoffeeScript позволяет писать более компактный код по сравнению с [[JavaScript]]<ref>[http://coffeescript.org/ Пример на титульной странице официального сайта]</ref>.
CoffeeScript позволяет писать более компактный код по сравнению с [[JavaScript]]<ref>{{Cite web |url=http://coffeescript.org/ |title=Пример на титульной странице официального сайта |access-date=2012-01-18 |archive-date=2017-06-09 |archive-url=https://web.archive.org/web/20170609022520/http://coffeescript.org/ |deadlink=no }}</ref>.
[[JavaScript]]-код, получаемый трансляцией из CoffeeScript, полностью проходит проверку [http://www.javascriptlint.com/ JavaScript Lint].
[[JavaScript]]-код, получаемый трансляцией из CoffeeScript, полностью проходит проверку [http://www.javascriptlint.com/ JavaScript Lint].


Строка 22: Строка 25:
Создателем языка является [[Ашкенас, Джереми|Джереми Ашкенас]].
Создателем языка является [[Ашкенас, Джереми|Джереми Ашкенас]].


Изначально компилятор был написан на [[Ruby]], но в версии 0.5, которая вышла [[21 февраля]] [[2010 год]]а, компилятор был реализован на самом же CoffeeScript.
Изначально компилятор был написан на [[Ruby]], но в версии 0.5, которая вышла [[21 февраля]] [[2010 год]]а, компилятор был реализован на самом же CoffeeScript.


CoffeeScript был радушно воспринят в [[Ruby]]-сообществе. Встроенная поддержка CoffeeScript была добавлена в [[фреймворк|веб-фреймворк]] [[Ruby on Rails]] с версии 3.1.
CoffeeScript был радушно воспринят в [[Ruby]]-сообществе. Встроенная поддержка CoffeeScript была добавлена в [[фреймворк|веб-фреймворк]] [[Ruby on Rails]] с версии 3.1.


== Преимущества использования ==
== Реализация ==
Использование пробелов как разграничительных знаков(вместо скобок, точек с запятой и прочих), делает CoffeeScript кратким. По сравнению с JavaScript, строка для того же конкретного кода в CoffeeScript сокращается примерно до половины (примерно на 55 % меньше). Так же CoffeeScript позволяет избежать проблем с объявлением области действия в программе, поскольку в отличие от JavaScript использование ключевого слова var перед объявлением переменной не требуется. Помимо этого, в CoffeeScript есть ряд удобных функций, таких как осмысление массивов, псевдонимы прототипов и классы, которые ещё больше сокращают количество вводимых символов.


== Недостатки использования ==
На официальном сайте языка есть раздел «try coffeescript», позволяющий выполнять программы на нём online<ref>{{Cite web|accessdate = 2016-01-04|title = Try CoffeeScript|url = http://coffeescript.org/#try:alert%2520%2522Hello%2520CoffeeScript!%2522|publisher = coffeescript.org}}</ref>. В отличие от, к примеру Try Ruby<ref>{{Cite web|accessdate = 2016-01-04|title = Try Ruby: learn the basics of the Ruby language in your browser.|url = http://tryruby.org|publisher = tryruby.org}}</ref>, при этом не будет происходить запросов к серверу, код компилируется и исполняется непосредственно в браузере.
Дополнительный этап компиляции между написанным кодом и кодом на JavaScript увеличивает общее время компиляции программы. CoffeeScript не является широко используемым, из за чего сложней искать источники информации по нему и кооперировать с другими разработчиками


== Примеры ==
== Синтаксис ==

=== Особенности ===
— отсутствие точек с запятой

— фигурные скобки ({}) заменены табуляцией

=== Комментарии ===
Синтаксис для комментариев заимствован из Ruby, где каждый однострочный комментарий начинается со знака решетки «#», а многострочные комментарии заключены между тремя символами решетки:<syntaxhighlight lang="coffeescript" line="1">
# A single line comment

###
A multiline
comment
###
</syntaxhighlight>

=== Пробелы ===
Вдохновившись Python, в CoffeeScript вместо фигурных скобок используется табуляция


=== Переменные ===
=== Переменные ===
Неподдерживаемость CoffeeScript глобальных переменных предотвращает ошибки доступа, которые могли возникнуть в JavaScript при случайном объявлении глобальной переменной.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
myVariable = "test"
</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var myVariable;
myVariable = "test";

</syntaxhighlight>

=== Функции ===
CoffeeScript удаляет довольно многословный оператор функции и заменяет его тонкой стрелкой: ->. Функции могут быть однострочными или отступать на несколько строк. Последнее выражение в функции неявно возвращается.
CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
func = -> "bar"
</syntaxhighlight>CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
func = ->
# An extra line
"bar"

</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var func;
func = function() {
return "bar";
};
</syntaxhighlight>

=== Аргументы функций ===
Аргументы функции записываются в круглые скобки перед стрелкой. Есть поддержка аргументов по умолчанию.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
times = (a = 1, b) -> a * b
</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var times;
times = function(a, b) {
if(a == null){
a = 1;
}
return a * b;
};
</syntaxhighlight>Так же можно использовать слайсы для приема нескольких аргументов

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
a = "Howdy!"

alert a
# Equivalent to:
alert(a)

alert inspect a
# Equivalent to:
alert(inspect(a))
</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var a;
a = "Howdy!";
alert(a);
alert(a);
alert(inspect(a));
alert(inspect(a));


</syntaxhighlight>

=== Вызов функций ===
Функции можно вызывать точно так же, как и в JavaScript, с помощью скобок (), apply() или call(). Однако, как и в Ruby, CoffeeScript автоматически вызывает функции, если они вызываются хотя бы с одним аргументом.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
myVariable = "test"
</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var myVariable;
myVariable = "test";

</syntaxhighlight>

=== Объектные литералы и объявление массивов ===
Объектные литералы задаются точно так же, как и в JavaScript, с помощью пары скобок и операторов ключ/значение. Однако, как и в случае с вызовом функций, в CoffeeScript скобки необязательны. Вместо запятых можно использовать отступы и новые строки.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
object1 = {one: 1, two: 2}

# Without braces
object2 = one: 1, two: 2

# Using new lines instead of commas
object3 =
one: 1
two: 2

User.create(name: "John Smith")

</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var object1, object2, object3;
object1 = {
one: 1,
two: 2
};
object2 = {
one: 1,
two: 2
};
object3 = {
one: 1,
two: 2
};
User.create({
name: "John Smith"
});

</syntaxhighlight>Аналогично, в массивах вместо запятых могут использоваться пробельные символы, хотя квадратные скобки ([]) по-прежнему обязательны.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
array1 = [1, 2, 3]

array2 = [
1
2
3
]

array3 = [1,2,3,]

</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var array1, array2, array3;
array1 = [1, 2, 3];
array2 = [1, 2, 3];
array3 = [1, 2, 3];

</syntaxhighlight>

=== Условные операторы ===
Если оператор if расположен в одной строке, необходимо использовать ключевое слово then, чтобы CoffeeScript знал, когда начинается блок. Условные операторы (?:) не поддерживаются, вместо них следует использовать однострочный оператор if/else.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
if true == true
"We're ok"

if true != true then "Panic"

# Equivalent to:
# (1 > 0) ? "Ok" : "Y2K!"
if 1 > 0 then "Ok" else "Y2K!"

</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
if (true === true) {
"We're ok";
}
if (true !== true) {
"Panic";
}
if (1 > 0) {
"Ok";
} else {
"Y2K!";
}

</syntaxhighlight>В CoffeeScript также используется идиома Ruby, позволяющая использовать суффиксные операторы if.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
alert "It's cold!" if heat < 5
</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
if (heat < 5) {
alert("It's cold!");
}
</syntaxhighlight>Вместо восклицательного знака (!) для отрицания можно также использовать ключевое слово not или оператор unless

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
if not true then "Panic"
</syntaxhighlight><syntaxhighlight lang="coffeescript" line="1">
unless true
"Panic"

</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
if (!true) {
"Panic";
}

</syntaxhighlight>Аналогично not, в CoffeeScript также вводится оператор is, который работает как === в JavaScript.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
if true is 1
"Type coercion fail!"

</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
if (true === 1) {
"Type coercion fail!";
}

</syntaxhighlight>

=== Интерполяция строк ===
CoffeeScript привносит в JavaScript интерполяцию строк в стиле Ruby. Строки в двойных кавычках могут содержать теги #{}, которые содержат выражения, подлежащие интерполяции в строку.

CoffeeScript:<syntaxhighlight lang="coffeescript" line="1">
favourite_color = "Blue. No, yel..."
question = "Bridgekeeper: What... is your favourite color?
Galahad: #{favourite_color}
Bridgekeeper: Wrong!
"
</syntaxhighlight>JavaScript:<syntaxhighlight lang="javascript" line="1">
var favourite_color, question;
favourite_color = "Blue. No, yel...";
question = "Bridgekeeper: What... is your favourite color? Galahad: " + favourite_color + " Bridgekeeper: Wrong! ";

</syntaxhighlight>

=== Циклы и вычисления ===

CoffeeScript:

JavaScript:

=== Массивы ===
CoffeeScript черпает вдохновение из Ruby, когда речь идет о создании массивов с помощью диапазонов. Диапазоны создаются двумя числовыми значениями, первой и последней позициями в диапазоне, разделенными … или ….. Если диапазон не имеет никакого префикса, CoffeeScript расширяет его до массива.


CoffeeScript:
CoffeeScript:
<source lang="ruby">
<source lang="ruby">
range = [1..5]
</source>

JavaScript:
<source lang="javascript">
var range;
range = [1, 2, 3, 4, 5];

</source>Если же диапазон указывается сразу после переменной, то CoffeeScript преобразует его в вызов метода slice().

CoffeeScript:
<source lang="ruby">
firstTwo = ["one", "two", "three"][0..1]
</source><source lang="ruby">
numbers = [0..9]
numbers[3..5] = [-3, -4, -5]

</source><source lang="ruby">
my = "my string"[0..2]
</source>

JavaScript:
<source lang="javascript">
var firstTwo;
firstTwo = ["one", "two", "three"].slice(0, 2);

</source><source lang="javascript">
var numbers, _ref;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
[].splice.apply(numbers, [3, 3].concat(_ref = [-3, -4, -5])), _ref;

</source><source lang="javascript">
var my;
my = "my string".slice(0, 3);

</source>Проверка наличия значения внутри массива всегда является проблемой в JavaScript, тем более что функция indexOf() пока не имеет полной кроссбраузерной поддержки. В CoffeeScript эта проблема решается с помощью оператора in:

CoffeeScript:
<source lang="ruby">
words = ["rattled", "roudy", "rebbles", "ranks"]
alert "Stop wagging me" if "ranks" in words

</source>

JavaScript:
<source lang="javascript">
var words;
var __indexOf = Array.prototype.indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (this[i] === item) return i;
}
return -1;
};
words = ["rattled", "roudy", "rebbles", "ranks"];
if (__indexOf.call(words, "ranks") >= 0) {
alert("Stop wagging me");
}

</source>

== Классы ==
CoffeeScript использует собственный прототип JavaScript для создания классов, добавляя немного синтаксического сахара для наследования статических свойств и сохранения контекста. В CoffeeScript используются функции-конструкторы, что означает возможность инстанцирования классов с помощью оператора new. CoffeeScript предоставляет сокращение для общего шаблона установки свойств экземпляра класса. Префикс аргумента @ позволяет CoffeeScript автоматически устанавливать аргументы как свойства экземпляра в конструкторе.
CoffeeScript:<source lang="coffeescript">
class Animal
constructor: (@name) ->
</source>

JavaScript:
<source lang="javascript">
var Animal;
Animal = (function() {
function Animal(name) {
this.name = name;
}
return Animal;
})();
</source>

=== Свойства экземпляра ===
Добавление дополнительных свойств экземпляра в класс очень просто, это точно такой же синтаксис, как и добавление свойств к объекту. Свойства должны быть правильно расположены с отступом внутри тела класса.

CoffeeScript:
<source lang="coffeescript">
class Animal
price: 5

sell: (customer) ->

animal = new Animal
animal.sell(new Customer)
</source>

JavaScript:
<source lang="javascript">
var Animal, animal;
Animal = (function() {
function Animal() {}
Animal.prototype.price = 5;
Animal.prototype.sell = function(customer) {};
return Animal;
})();
animal = new Animal;
animal.sell(new Customer);
</source>

=== Статичные свойства ===
Внутри определения класса, ключевое слово this и @ ссылаются на объект класса

CoffeeScript:
<source lang="coffeescript">
class Animal
this.find_ = (name) ->
@.age_ = (age) ->

Animal.find_("Parrot")
</source>

JavaScript:
<source lang="javascript">
var Animal;
Animal = (function() {
function Animal() {}
Animal.find_ = function(name) {};
Anumal.age_ = function(age){};
return Animal;
})();
Animal.find_("Parrot");
</source>

=== Наследование ===
Наследование класса происходит при помощи ключевого слова extends

CoffeeScript:
<source lang="coffeescript">
class Animal
constructor: (@name) ->

alive: ->
false

class Parrot extends Animal
constructor: ->
super("Parrot")

dead: ->
not @alive()
</source>

JavaScript:
<source lang="javascript">
var Animal, Parrot;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
Animal = (function() {
function Animal(name) {
this.name = name;
}
Animal.prototype.alive = function() {
return false;
};
return Animal;
})();
Parrot = (function() {
__extends(Parrot, Animal);
function Parrot() {
Parrot.__super__.constructor.call(this, "Parrot");
}
Parrot.prototype.dead = function() {
return !this.alive();
};
return Parrot;
})();
</source>Cтатические свойства копируются в подклассы, а не наследуются по прототипу, как свойства экземпляра. Это связано с особенностями реализации прототипической архитектуры JavaScript и является трудноразрешимой проблемой.

== [[Идиома (программирование)|Идиомы]] ==

=== Each ===
В JavaScript для итерации по каждому элементу массива можно использовать либо недавно добавленную функцию forEach(), либо же цикл for в стиле C. Хотя синтаксис forEach() гораздо более лаконичен и удобен для чтения, он страдает тем недостатком, что функция обратного вызова будет вызываться на каждой итерации массива, и поэтому работает гораздо медленнее, чем эквивалентный цикл for. Синтаксис CoffeeScript обеспечивает ту же выразительность, что и forEach(), но без ограничений по скорости.
CoffeeScript:<source lang="coffeescript">
myFunction(item) for item in array
</source>

JavaScript:
<source lang="javascript">
var item, _i, _len;
for (_i = 0, _len = array.length; _i < _len; _i++) {
item = array[_i];
myFunction(item);
}
</source>

=== Includes ===
Проверка того, находится ли значение внутри массива, обычно выполняется с помощью функции indexOf(). CoffeeScript использует Array.prototype.indexOf() и, при необходимости, шимминг, чтобы определить, находится ли значение внутри массива. К сожалению, это означает, что аналогичный синтаксис не будет работать для строк. Приходится возвращаться к использованию indexOf() и проверять, не будет ли результат отрицательным или, что ещё лучше, использовать побитовый оператор, чтобы не делать сравнение −1.
CoffeeScript:<source lang="coffeescript">
string = "a long test string"
included = !!~ string.indexOf "test"
</source>

JavaScript:
<source lang="javascript">
var included, string;
string = "a long test string";
included = !!~string.indexOf("test");
</source>

=== Итерации ===
Для итерации в JavaScript используется оператор in. В CoffeeScript Вместо этого оператор был переименован в of, и его можно использовать следующим образом:

CoffeeScript:
<source lang="coffeescript">
object = {one: 1, two: 2}
alert("#{key} = #{value}") for key, value of object
</source>

JavaScript:
<source lang="javascript">
var key, object, value;
object = {
one: 1,
two: 2
};
for (key in object) {
value = object[key];
alert("" + key + " = " + value);
}
</source>

=== Min/Max ===
Math.max и Math.min принимают несколько аргументов, поэтому можно легко использовать … для передачи им массива, получая максимальное и минимальное значения в массиве.

CoffeeScript:
<source lang="coffeescript">
Math.max [14, 35, -7, 46, 98]... # 98
Math.min [14, 35, -7, 46, 98]... # -7
</source>

JavaScript:
<source lang="javascript">
Math.max.apply(Math, [14, 35, -7, 46, 98]);
Math.min.apply(Math, [14, 35, -7, 46, 98]);
</source>

=== And/or ===
В руководствах по стилю CoffeeScript указано, что or предпочтительнее, чем ||, а and предпочтительнее, чем &&. Это предпочтение более английского стиля также относится к использованию is вместо == и isnt вместо !=. Одним из чрезвычайно приятных дополнений к CoffeeScript является 'or equals' — паттерн, который рубинисты могут узнать как ||=:

CoffeeScript:
<source lang="coffeescript">
string = "migrating coconuts"
string == string # true
string is string # true



</source>

JavaScript:
<source lang="javascript">
var string;
string = "migrating coconuts";
string === string;
string === string;
</source>

=== Внешние библиотеки ===
Использование внешних библиотек — это то же самое, что вызов функций из библиотек CoffeeScript, поскольку в конечном итоге все компилируется в JavaScript.

CoffeeScript:
<source lang="coffeescript">
# Use local alias
$ = jQuery

$ ->
# DOMContentLoaded
$(".el").click ->
alert("Clicked!")
</source>

JavaScript:
<source lang="javascript">
var $;
$ = jQuery;
$(function() {
return $(".el").click(function() {
return alert("Clicked!");
});
});
</source>

=== Private variables ===
Ключевое слово do в CoffeeScript позволяет выполнять функции немедленно, что является отличным способом инкапсуляции области видимости и защиты переменных.

== Реализация ==
На официальном сайте языка есть раздел «try coffeescript», позволяющий выполнять программы на нём online<ref>{{Cite web|accessdate = 2016-01-04|title = Try CoffeeScript|url = http://coffeescript.org/#try:alert%2520%2522Hello%2520CoffeeScript!%2522|publisher = coffeescript.org|archive-date = 2017-06-09|archive-url = https://web.archive.org/web/20170609022520/http://coffeescript.org/#try:alert%2520%2522Hello%2520CoffeeScript!%2522|deadlink = no}}</ref>. В отличие, к примеру, от Try Ruby<ref>{{Cite web|accessdate = 2016-01-04|title = Try Ruby: learn the basics of the Ruby language in your browser.|url = http://tryruby.org|publisher = tryruby.org|archive-date = 2011-09-28|archive-url = https://web.archive.org/web/20110928182220/http://tryruby.org/|deadlink = no}}</ref>, при этом не будет происходить запросов к серверу, код компилируется и исполняется непосредственно в браузере.

== Примеры ==

=== Переменные ===
CoffeeScript:
<source lang="coffeescript">
age = 2
age = 2
male = true
male = true
name = "Влад"
name = "Матвей"


</source>
</source>
Строка 44: Строка 585:
JavaScript:
JavaScript:
<source lang="javascript">
<source lang="javascript">
var age = 2,
let age = 2,
male = true,
male = true,
name = "Матвей";
name = "Матвей";
Строка 50: Строка 591:


=== Функции ===
=== Функции ===

CoffeeScript:
CoffeeScript:
<source lang="ruby">
<source lang="ruby">
Строка 61: Строка 601:
JavaScript с использованием [[ECMAScript]] 2015:
JavaScript с использованием [[ECMAScript]] 2015:
<source lang="javascript">
<source lang="javascript">
const say = ( speech ) => alert( speech );
const say = speech => alert(speech);
say( 'Привет мир!' );
say('Привет мир!');
</source>
</source>


Строка 74: Строка 614:


=== Классы и объекты ===
=== Классы и объекты ===

CoffeeScript:
CoffeeScript:
<source lang="coffeescript">
<source lang="coffeescript">
Строка 91: Строка 630:
<source lang="javascript">
<source lang="javascript">
class Human {
class Human {
constructor( name ) {
constructor(name) {
this.name = name;
this.name = name;
}
}
Строка 97: Строка 636:


class Baby extends Human {
class Baby extends Human {
say( msg ) {
say(msg) {
alert( `${this.name} говорит '${msg}'` );
alert(`${this.name} говорит '${msg}'`);
}
}
sayHi() {
sayHi() {
this.say( 'здравствуй!' );
this.say('здравствуй!');
}
}
}
}


const matt = new Baby( 'Матвей' );
const matt = new Baby('Матвей');
matt.sayHi();
matt.sayHi();
</source>
</source>
Строка 162: Строка 701:
@hi = -> msg # динамический метод, записан в экземпляр Test
@hi = -> msg # динамический метод, записан в экземпляр Test
</source>
</source>

== Компилятор ==
Интересным является тот факт, что компилятор для CoffeeScript написан на самом CoffeeScript


== См. также ==
== См. также ==
Строка 175: Строка 717:
* {{книга|автор=Марк Бейтс.|заглавие=CoffeeScript. Второе дыхание JavaScript |оригинал=''Mark Bates.'' Programming in CoffeeScript|место=М.|издательство=[[ДМК]]|год=2012|страниц=312|isbn=978-5-94074-842-7|тираж=300|ref = Бейтс}}
* {{книга|автор=Марк Бейтс.|заглавие=CoffeeScript. Второе дыхание JavaScript |оригинал=''Mark Bates.'' Programming in CoffeeScript|место=М.|издательство=[[ДМК]]|год=2012|страниц=312|isbn=978-5-94074-842-7|тираж=300|ref = Бейтс}}
* {{Книга|автор = Alex MacCaw|заглавие = The Little Book on CoffeeScript|ответственный = |издание = |место = |издательство = O'Reilly Media|год = 2011|страницы = |страниц = 60|isbn = 9781449321055,|ссылка = https://arcturo.github.io/library/coffeescript/|ref = MacCaw}}
* {{Книга|автор = Alex MacCaw|заглавие = The Little Book on CoffeeScript|ответственный = |издание = |место = |издательство = O'Reilly Media|год = 2011|страницы = |страниц = 60|isbn = 9781449321055,|ссылка = https://arcturo.github.io/library/coffeescript/|ref = MacCaw}}
* [https://archive.is/20121208174724/http://coffeescriptcookbook.com/ CoffeeScript Cookbook], сборник рецептов CoffeeScript от сообщества.
* [https://archive.today/20121208174724/http://coffeescriptcookbook.com/ CoffeeScript Cookbook], сборник рецептов CoffeeScript от сообщества.
* [https://autotelicum.github.com/Smooth-CoffeeScript/ Smooth CoffeeScript], свободная электронная книга о CoffeeScript. Доступна в двух вариантах с исходным кодом примеров.
* [https://autotelicum.github.com/Smooth-CoffeeScript/ Smooth CoffeeScript] {{Wayback|url=https://autotelicum.github.com/Smooth-CoffeeScript/ |date=20110711231834 }}, свободная электронная книга о CoffeeScript. Доступна в двух вариантах с исходным кодом примеров.
* {{Cite web|accessdate = 2016-01-10|date = 2012-07-19|lang = ru|title = Ваша первая чашечка CoffeeScript : Часть 1. Приступаем к работе|url = https://www.ibm.com/developerworks/ru/library/wa-coffee1/|publisher = [[DeveloperWorks]]|author = Майкл Галпин}}
* {{Cite web|accessdate = 2016-01-10|date = 2012-07-19|lang = ru|title = Ваша первая чашечка CoffeeScript : Часть 1. Приступаем к работе|url = https://www.ibm.com/developerworks/ru/library/wa-coffee1/|publisher = [[DeveloperWorks]]|author = Майкл Галпин}}
** {{Cite web|accessdate = 2016-01-10|date = 2012-07-18|title = Ваша первая чашечка CoffeeScript: Часть 2. Изучение языка на практических примерах|url = http://www.ibm.com/developerworks/ru/library/wa-coffee2/}}
** {{Cite web|accessdate = 2016-01-10|date = 2012-07-18|title = Ваша первая чашечка CoffeeScript: Часть 2. Изучение языка на практических примерах|url = http://www.ibm.com/developerworks/ru/library/wa-coffee2/}}
** {{Cite web|accessdate = 2016-01-10|date = 2012-07-20|title = Ваша первая чашечка CoffeeScript: Часть 3. Использование CoffeeScript на стороне клиента|url = http://www.ibm.com/developerworks/ru/library/wa-coffee3/}}
** {{Cite web|accessdate = 2016-01-10|date = 2012-07-20|title = Ваша первая чашечка CoffeeScript: Часть 3. Использование CoffeeScript на стороне клиента|url = http://www.ibm.com/developerworks/ru/library/wa-coffee3/}}
**{{Cite web|accessdate = 2016-01-10|date = 2012-07-20|title = Ваша первая чашечка CoffeeScript: Часть 4. Использование CoffeeScript на стороне сервера|url = http://www.ibm.com/developerworks/ru/library/wa-coffee4/}}
** {{Cite web|accessdate = 2016-01-10|date = 2012-07-20|title = Ваша первая чашечка CoffeeScript: Часть 4. Использование CoffeeScript на стороне сервера|url = http://www.ibm.com/developerworks/ru/library/wa-coffee4/}}
* {{Cite web|accessdate = 2016-01-10|date = 2012-12-03|lang = ru|title = Функциональный JavaScript с применением CoffeeScript и Node|url = http://www.ibm.com/developerworks/ru/library/j-coffeescript/|publisher = [[DeveloperWorks]]|author = Эндрю Гловер}}
* {{Cite web|accessdate = 2016-01-10|date = 2012-12-03|lang = ru|title = Функциональный JavaScript с применением CoffeeScript и Node|url = http://www.ibm.com/developerworks/ru/library/j-coffeescript/|publisher = [[DeveloperWorks]]|author = Эндрю Гловер}}
* Alex MacCaw. [https://arcturo.github.io/library/coffeescript/ The Little Book on CoffeeScript]


== Ссылки ==
== Ссылки ==
Строка 200: Строка 743:
[[Категория:Семейство языков программирования JavaScript]]
[[Категория:Семейство языков программирования JavaScript]]
[[Категория:Прототипно-ориентированные языки программирования]]
[[Категория:Прототипно-ориентированные языки программирования]]
[[Категория:Транспиляция]]

Текущая версия от 12:44, 22 сентября 2024

CoffeeScript
Изображение логотипа
Класс языка
Появился в 13 декабря 2009
Автор Джереми Ашкенас
Расширение файлов .coffee
Выпуск 2.7.0[1] (24 апреля 2022; 2 года назад (2022-04-24))
Испытал влияние JavaScript, Python, Ruby, Haskell, Erlang
Повлиял на MoonScript, LiveScript
Лицензия лицензия MIT[2]
Сайт coffeescript.org
ОС кроссплатформенность

CoffeeScript ([’kɔ:fɪ skrɪpt]; кофи скрипт) — язык программирования, транслируемый в JavaScript. CoffeeScript добавляет синтаксический сахар в духе Ruby, Python, Haskell и Erlang для того, чтобы улучшить читаемость кода и уменьшить его размер. CoffeeScript позволяет писать более компактный код по сравнению с JavaScript[3]. JavaScript-код, получаемый трансляцией из CoffeeScript, полностью проходит проверку JavaScript Lint.

Создателем языка является Джереми Ашкенас.

Изначально компилятор был написан на Ruby, но в версии 0.5, которая вышла 21 февраля 2010 года, компилятор был реализован на самом же CoffeeScript.

CoffeeScript был радушно воспринят в Ruby-сообществе. Встроенная поддержка CoffeeScript была добавлена в веб-фреймворк Ruby on Rails с версии 3.1.

Преимущества использования

[править | править код]

Использование пробелов как разграничительных знаков(вместо скобок, точек с запятой и прочих), делает CoffeeScript кратким. По сравнению с JavaScript, строка для того же конкретного кода в CoffeeScript сокращается примерно до половины (примерно на 55 % меньше). Так же CoffeeScript позволяет избежать проблем с объявлением области действия в программе, поскольку в отличие от JavaScript использование ключевого слова var перед объявлением переменной не требуется. Помимо этого, в CoffeeScript есть ряд удобных функций, таких как осмысление массивов, псевдонимы прототипов и классы, которые ещё больше сокращают количество вводимых символов.

Недостатки использования

[править | править код]

Дополнительный этап компиляции между написанным кодом и кодом на JavaScript увеличивает общее время компиляции программы. CoffeeScript не является широко используемым, из за чего сложней искать источники информации по нему и кооперировать с другими разработчиками

Особенности

[править | править код]

— отсутствие точек с запятой

— фигурные скобки ({}) заменены табуляцией

Комментарии

[править | править код]

Синтаксис для комментариев заимствован из Ruby, где каждый однострочный комментарий начинается со знака решетки «#», а многострочные комментарии заключены между тремя символами решетки:

# A single line comment

###
    A multiline 
    comment
###

Вдохновившись Python, в CoffeeScript вместо фигурных скобок используется табуляция

Переменные

[править | править код]

Неподдерживаемость CoffeeScript глобальных переменных предотвращает ошибки доступа, которые могли возникнуть в JavaScript при случайном объявлении глобальной переменной.

CoffeeScript:

myVariable = "test"

JavaScript:

var myVariable;
myVariable = "test";

CoffeeScript удаляет довольно многословный оператор функции и заменяет его тонкой стрелкой: ->. Функции могут быть однострочными или отступать на несколько строк. Последнее выражение в функции неявно возвращается.

CoffeeScript:

func = -> "bar"

CoffeeScript:

func = ->
  # An extra line
  "bar"

JavaScript:

var func;
func = function() {
  return "bar";
};

Аргументы функций

[править | править код]

Аргументы функции записываются в круглые скобки перед стрелкой. Есть поддержка аргументов по умолчанию.

CoffeeScript:

times = (a = 1, b) -> a * b

JavaScript:

var times;
times = function(a, b) {
    if(a == null){
        a = 1;
    }
  return a * b;
};

Так же можно использовать слайсы для приема нескольких аргументов CoffeeScript:

a = "Howdy!"

alert a
# Equivalent to:
alert(a)

alert inspect a
# Equivalent to:
alert(inspect(a))

JavaScript:

var a;
a = "Howdy!";
alert(a);
alert(a);
alert(inspect(a));
alert(inspect(a));

Вызов функций

[править | править код]

Функции можно вызывать точно так же, как и в JavaScript, с помощью скобок (), apply() или call(). Однако, как и в Ruby, CoffeeScript автоматически вызывает функции, если они вызываются хотя бы с одним аргументом.

CoffeeScript:

myVariable = "test"

JavaScript:

var myVariable;
myVariable = "test";

Объектные литералы и объявление массивов

[править | править код]

Объектные литералы задаются точно так же, как и в JavaScript, с помощью пары скобок и операторов ключ/значение. Однако, как и в случае с вызовом функций, в CoffeeScript скобки необязательны. Вместо запятых можно использовать отступы и новые строки.

CoffeeScript:

object1 = {one: 1, two: 2}

# Without braces
object2 = one: 1, two: 2

# Using new lines instead of commas
object3 = 
  one: 1
  two: 2

User.create(name: "John Smith")

JavaScript:

var object1, object2, object3;
object1 = {
  one: 1,
  two: 2
};
object2 = {
  one: 1,
  two: 2
};
object3 = {
  one: 1,
  two: 2
};
User.create({
  name: "John Smith"
});

Аналогично, в массивах вместо запятых могут использоваться пробельные символы, хотя квадратные скобки ([]) по-прежнему обязательны. CoffeeScript:

array1 = [1, 2, 3]

array2 = [
  1
  2
  3
]

array3 = [1,2,3,]

JavaScript:

var array1, array2, array3;
array1 = [1, 2, 3];
array2 = [1, 2, 3];
array3 = [1, 2, 3];

Условные операторы

[править | править код]

Если оператор if расположен в одной строке, необходимо использовать ключевое слово then, чтобы CoffeeScript знал, когда начинается блок. Условные операторы (?:) не поддерживаются, вместо них следует использовать однострочный оператор if/else.

CoffeeScript:

if true == true
  "We're ok"

if true != true then "Panic"

# Equivalent to:
#  (1 > 0) ? "Ok" : "Y2K!"
if 1 > 0 then "Ok" else "Y2K!"

JavaScript:

if (true === true) {
  "We're ok";
}
if (true !== true) {
  "Panic";
}
if (1 > 0) {
  "Ok";
} else {
  "Y2K!";
}

В CoffeeScript также используется идиома Ruby, позволяющая использовать суффиксные операторы if. CoffeeScript:

alert "It's cold!" if heat < 5

JavaScript:

if (heat < 5) {
  alert("It's cold!");
}

Вместо восклицательного знака (!) для отрицания можно также использовать ключевое слово not или оператор unless CoffeeScript:

if not true then "Panic"
unless true
  "Panic"

JavaScript:

if (!true) {
  "Panic";
}

Аналогично not, в CoffeeScript также вводится оператор is, который работает как === в JavaScript. CoffeeScript:

if true is 1
  "Type coercion fail!"

JavaScript:

if (true === 1) {
  "Type coercion fail!";
}

Интерполяция строк

[править | править код]

CoffeeScript привносит в JavaScript интерполяцию строк в стиле Ruby. Строки в двойных кавычках могут содержать теги #{}, которые содержат выражения, подлежащие интерполяции в строку.

CoffeeScript:

favourite_color = "Blue. No, yel..."
question = "Bridgekeeper: What... is your favourite color?
            Galahad: #{favourite_color}
            Bridgekeeper: Wrong!
"

JavaScript:

var favourite_color, question;
favourite_color = "Blue. No, yel...";
question = "Bridgekeeper: What... is your favourite color?            Galahad: " + favourite_color + "            Bridgekeeper: Wrong!            ";

Циклы и вычисления

[править | править код]

CoffeeScript:

JavaScript:

CoffeeScript черпает вдохновение из Ruby, когда речь идет о создании массивов с помощью диапазонов. Диапазоны создаются двумя числовыми значениями, первой и последней позициями в диапазоне, разделенными … или ….. Если диапазон не имеет никакого префикса, CoffeeScript расширяет его до массива.

CoffeeScript:

range = [1..5]

JavaScript:

var range;
range = [1, 2, 3, 4, 5];

Если же диапазон указывается сразу после переменной, то CoffeeScript преобразует его в вызов метода slice().

CoffeeScript:

firstTwo = ["one", "two", "three"][0..1]
numbers = [0..9]
numbers[3..5] = [-3, -4, -5]
my = "my string"[0..2]

JavaScript:

var firstTwo;
firstTwo = ["one", "two", "three"].slice(0, 2);
var numbers, _ref;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
[].splice.apply(numbers, [3, 3].concat(_ref = [-3, -4, -5])), _ref;
var my;
my = "my string".slice(0, 3);

Проверка наличия значения внутри массива всегда является проблемой в JavaScript, тем более что функция indexOf() пока не имеет полной кроссбраузерной поддержки. В CoffeeScript эта проблема решается с помощью оператора in:

CoffeeScript:

words = ["rattled", "roudy", "rebbles", "ranks"]
alert "Stop wagging me" if "ranks" in words

JavaScript:

var words;
var __indexOf = Array.prototype.indexOf || function(item) {
  for (var i = 0, l = this.length; i < l; i++) {
    if (this[i] === item) return i;
  }
  return -1;
};
words = ["rattled", "roudy", "rebbles", "ranks"];
if (__indexOf.call(words, "ranks") >= 0) {
  alert("Stop wagging me");
}

CoffeeScript использует собственный прототип JavaScript для создания классов, добавляя немного синтаксического сахара для наследования статических свойств и сохранения контекста. В CoffeeScript используются функции-конструкторы, что означает возможность инстанцирования классов с помощью оператора new. CoffeeScript предоставляет сокращение для общего шаблона установки свойств экземпляра класса. Префикс аргумента @ позволяет CoffeeScript автоматически устанавливать аргументы как свойства экземпляра в конструкторе.

CoffeeScript:

class Animal
  constructor: (@name) ->

JavaScript:

var Animal;
Animal = (function() {
  function Animal(name) {
    this.name = name;
  }
  return Animal;
})();

Свойства экземпляра

[править | править код]

Добавление дополнительных свойств экземпляра в класс очень просто, это точно такой же синтаксис, как и добавление свойств к объекту. Свойства должны быть правильно расположены с отступом внутри тела класса.

CoffeeScript:

class Animal
  price: 5

  sell: (customer) ->

animal = new Animal
animal.sell(new Customer)

JavaScript:

var Animal, animal;
Animal = (function() {
  function Animal() {}
  Animal.prototype.price = 5;
  Animal.prototype.sell = function(customer) {};
  return Animal;
})();
animal = new Animal;
animal.sell(new Customer);

Статичные свойства

[править | править код]

Внутри определения класса, ключевое слово this и @ ссылаются на объект класса

CoffeeScript:

class Animal
  this.find_ = (name) -> 
  @.age_ = (age) ->

Animal.find_("Parrot")

JavaScript:

var Animal;
Animal = (function() {
  function Animal() {}
  Animal.find_ = function(name) {};
  Anumal.age_ = function(age){};
  return Animal;
})();
Animal.find_("Parrot");

Наследование

[править | править код]

Наследование класса происходит при помощи ключевого слова extends

CoffeeScript:

class Animal
  constructor: (@name) ->

  alive: ->
    false

class Parrot extends Animal
  constructor: ->
    super("Parrot")

  dead: ->
    not @alive()

JavaScript:

var Animal, Parrot;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
  for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
  function ctor() { this.constructor = child; }
  ctor.prototype = parent.prototype;
  child.prototype = new ctor;
  child.__super__ = parent.prototype;
  return child;
};
Animal = (function() {
  function Animal(name) {
    this.name = name;
  }
  Animal.prototype.alive = function() {
    return false;
  };
  return Animal;
})();
Parrot = (function() {
  __extends(Parrot, Animal);
  function Parrot() {
    Parrot.__super__.constructor.call(this, "Parrot");
  }
  Parrot.prototype.dead = function() {
    return !this.alive();
  };
  return Parrot;
})();

Cтатические свойства копируются в подклассы, а не наследуются по прототипу, как свойства экземпляра. Это связано с особенностями реализации прототипической архитектуры JavaScript и является трудноразрешимой проблемой.

В JavaScript для итерации по каждому элементу массива можно использовать либо недавно добавленную функцию forEach(), либо же цикл for в стиле C. Хотя синтаксис forEach() гораздо более лаконичен и удобен для чтения, он страдает тем недостатком, что функция обратного вызова будет вызываться на каждой итерации массива, и поэтому работает гораздо медленнее, чем эквивалентный цикл for. Синтаксис CoffeeScript обеспечивает ту же выразительность, что и forEach(), но без ограничений по скорости.

CoffeeScript:

myFunction(item) for item in array

JavaScript:

var item, _i, _len;
for (_i = 0, _len = array.length; _i < _len; _i++) {
  item = array[_i];
  myFunction(item);
}

Проверка того, находится ли значение внутри массива, обычно выполняется с помощью функции indexOf(). CoffeeScript использует Array.prototype.indexOf() и, при необходимости, шимминг, чтобы определить, находится ли значение внутри массива. К сожалению, это означает, что аналогичный синтаксис не будет работать для строк. Приходится возвращаться к использованию indexOf() и проверять, не будет ли результат отрицательным или, что ещё лучше, использовать побитовый оператор, чтобы не делать сравнение −1.

CoffeeScript:

string   = "a long test string"
included = !!~ string.indexOf "test"

JavaScript:

var included, string;
string = "a long test string";
included = !!~string.indexOf("test");

Для итерации в JavaScript используется оператор in. В CoffeeScript Вместо этого оператор был переименован в of, и его можно использовать следующим образом:

CoffeeScript:

object = {one: 1, two: 2}
alert("#{key} = #{value}") for key, value of object

JavaScript:

var key, object, value;
object = {
  one: 1,
  two: 2
};
for (key in object) {
  value = object[key];
  alert("" + key + " = " + value);
}

Math.max и Math.min принимают несколько аргументов, поэтому можно легко использовать … для передачи им массива, получая максимальное и минимальное значения в массиве.

CoffeeScript:

Math.max [14, 35, -7, 46, 98]... # 98
Math.min [14, 35, -7, 46, 98]... # -7

JavaScript:

Math.max.apply(Math, [14, 35, -7, 46, 98]);
Math.min.apply(Math, [14, 35, -7, 46, 98]);

В руководствах по стилю CoffeeScript указано, что or предпочтительнее, чем ||, а and предпочтительнее, чем &&. Это предпочтение более английского стиля также относится к использованию is вместо == и isnt вместо !=. Одним из чрезвычайно приятных дополнений к CoffeeScript является 'or equals' — паттерн, который рубинисты могут узнать как ||=:

CoffeeScript:

string = "migrating coconuts"
string == string # true
string is string # true

JavaScript:

var string;
string = "migrating coconuts";
string === string;
string === string;

Внешние библиотеки

[править | править код]

Использование внешних библиотек — это то же самое, что вызов функций из библиотек CoffeeScript, поскольку в конечном итоге все компилируется в JavaScript.

CoffeeScript:

# Use local alias
$ = jQuery

$ ->
  # DOMContentLoaded
  $(".el").click ->
    alert("Clicked!")

JavaScript:

var $;
$ = jQuery;
$(function() {
  return $(".el").click(function() {
    return alert("Clicked!");
  });
});

Ключевое слово do в CoffeeScript позволяет выполнять функции немедленно, что является отличным способом инкапсуляции области видимости и защиты переменных.

Реализация

[править | править код]

На официальном сайте языка есть раздел «try coffeescript», позволяющий выполнять программы на нём online[4]. В отличие, к примеру, от Try Ruby[5], при этом не будет происходить запросов к серверу, код компилируется и исполняется непосредственно в браузере.

Переменные

[править | править код]

CoffeeScript:

age  = 2
male = true
name = "Матвей"

JavaScript:

let age = 2,
    male = true,
    name = "Матвей";

CoffeeScript:

say = (speech) ->
  alert speech

say "Привет мир!"

JavaScript с использованием ECMAScript 2015:

const say = speech => alert(speech);
say('Привет мир!');

JavaScript:

var say = function(speech) {
  alert(speech);
};
say("Привет мир!");

Классы и объекты

[править | править код]

CoffeeScript:

class Human
  constructor : (@name) ->

class Baby extends Human
  say   : (msg) -> alert "#{@name} говорит '#{msg}'"
  sayHi : -> @say('здравствуй!')

matt = new Baby("Матвей")
matt.sayHi()

JavaScript с использованием ECMAScript 2015:

class Human {
	constructor(name) {
		this.name = name;
	}
}

class Baby extends Human {
	say(msg) {
		alert(`${this.name} говорит '${msg}'`);
	}
	sayHi()	{
		this.say('здравствуй!');
	}
}

const matt = new Baby('Матвей');
matt.sayHi();

Аналог на JavaScript (именно аналог, а не результат компиляции):

function Human(name){
  this.name = name;
}

function Baby(name){
  Human.call(this, name);
}

Baby.prototype = Object.create(Human.prototype);
Baby.prototype.say = function(msg){
  alert(this.name + ' говорит ' + msg);
};
Baby.prototype.sayHi = function(){
  this.say('здравствуй!');
};
Baby.prototype.constructor = Human;

var matt = new Baby("Матвей");
matt.sayHi();

Примечание: в JavaScript при работе с «классами» (конструктор + прототипы + функции для наследования и смешивания) часто используют обёртки (MooTools, AtomJS и другие). Аналогия на JavaScript с классовой обёрткой AtomJS:

var Human = Class({
  initialize : function(name) {
    this.name = name;
  }
});

var Baby = Class({
  Extends : Human,
  say : function(msg) {
    alert(this.name + ' говорит ' + msg);
  },
  sayHi : function() {
    this.say('здравствуй!');
  }
});

var matt = new Baby("Матвей");
matt.sayHi();

Пример класса CoffeeScript с различными видами свойств.

class Test
  say   = (msg) -> alert msg       # приватный метод
  @echo = (msg) -> console.log msg # статический метод, записан в Test
  setHi : (msg) ->                 # динамический метод, записан в Test.prototype
    @hi = -> msg                   # динамический метод, записан в экземпляр Test

Компилятор

[править | править код]

Интересным является тот факт, что компилятор для CoffeeScript написан на самом CoffeeScript

Примечания

[править | править код]
  1. "2.7.0". Архивировано 23 июня 2022. Дата обращения: 23 июня 2022.
  2. The coffeescript Open Source Project on Open Hub: Licenses Page — 2006.
  3. Пример на титульной странице официального сайта. Дата обращения: 18 января 2012. Архивировано 9 июня 2017 года.
  4. Try CoffeeScript. coffeescript.org. Дата обращения: 4 января 2016. Архивировано 9 июня 2017 года.
  5. Try Ruby: learn the basics of the Ruby language in your browser. tryruby.org. Дата обращения: 4 января 2016. Архивировано 28 сентября 2011 года.

Литература

[править | править код]

Смежные проекты:

  • Компилятор CoffeeScript для Windows
  • CoffeeKup, шаблонизатор и движок для генерации HTML-кода на CoffeeScript.
  • Prepros, компилирует на лету CoffeeScript. Под Windows и OSX (также компилирует LESS, Stylus, Haml, Jade, Markdown, Slim, SASS)