CoffeeScript
Последнее изменение этой страницы: 00:07, 9 июня 2016.
Спроектировано | Джереми Ашкенас |
---|---|
Портал: | http://coffeescript.org/ |
CoffeeScript ([’kɔ:fɪ skrɪpt]; кофи скрипт) — компактный высокоуровневый язык программирования, транслируемый в JavaScript. CoffeeScript использует синтаксический сахар в стиле Ruby, Python, Haskell и Erlang, чтобы улучшить читаемость кода и уменьшить его размер. CoffeeScript позволяет писать более компактный код по сравнению с JavaScript. JavaScript-код, получаемый трансляцией из CoffeeScript, полностью проходит проверку JavaScript Lint.
Изначально компилятор языка был написан на Ruby. В версии 0.5, которая вышла 21 февраля 2010 года, компилятор был реализован на самом CoffeeScript. Язык был радушно воспринят в Ruby-сообществе. Встроенная поддержка CoffeeScript была добавлена в веб-фреймворк Ruby on Rails с версии 3.1.
Содержание
Преимущества перед JavaScript
JavaScript на сегодня является одним из наиболее популярных и распространенных языков программирования. Он обычно используется как встраиваемый язык для программного доступа к объектам приложений. Наиболее широкое применение находит в браузерах как язык сценариев для придания интерактивности веб-страницам.
Однако многие разработчики отвергают и критикуют JavaScript, во многом из-за его алогичного синтаксиса и несовместимых реализаций. С точки зрения синтаксиса JavaScript очень разнороден. Он разделяет, например, многие идеи языка Scheme, но не его синтаксис - вместо этого в JavaScript используется Cи-подобный синтаксис. Результатом стал язык, позаимствовавший идеи функциональных языков, но с многословным синтаксисом, лишенным естественных конструкций для выражения этих идей.
JavaScript — это также и объектно-ориентированный язык с наследованием, но в то же время - это прототипичный язык. Он не основан на классах, как языки, используемые большинством платформ приложений. Поэтому программирование приложений на JavaScript может оказаться весьма громоздким.
CoffeeScript во многом устраняет недостатки своего предшественника:
- предоставляет простой синтаксис с меньшим количеством балласта;
- использует пробелы как способ организации блоков кода;
- обеспечивает простой синтаксис для выражения функций;
- обеспечивает наследование на основе классов.
При этом CoffeeScript не является интерпретируемым языком и не использует отдельные библиотеки времени выполнения - весь код на CoffeeScript компилируется в соответствующий код на JavaScript. Таким образом, CoffeeScript предоставляет программисту синтаксис, который позволяет использовать всю силу JavaScript с минимальными накладными расходами.
Предварительные требования
CoffeeScript распространяется как пакет Node.js с помощью менеджера пакетов Node ― NPM. Таким образом, для написания и компиляции кода на CoffeeScript необходимо предварительно установить Node.Js. Кроме того, для работы потребуется среда исполнения JavaScript. Для этого подходит виртуальная машина JavaScript V8, лежащая в основе Node.js. Устанавливается CoffeeScript также как и другие пакеты Node.Js: npm install -g coffee-script
Компиляция
Чтобы запустить компилятор CoffeeScript, достаточно ввести команду coffee -c<имяфайла>: например coffee -ctest.coffee. Результатом выполнения команды будет одноименный файл .js с соответствующим кодом на JavaScript. Также можно указывать не только конкретный файл, но и папку, содержащую исходные коды: coffee --compile --output lib/ src/
Файл с исходным кодом test.coffee
console.log "Hello world"
Результирующий файл test.js
(function() {
console.log("Hello world");
}).call(this);
JavaScript поддерживает определение области видимости только на уровне функции. Из-за этого компилятор CoffeeScript заключает код в анонимную функцию, тем самым гарантируя, что переменная будет ограничена только этой функцией и не станет глобальной (и не заменит существующую глобальную переменную).
Синтаксис
Функции
Напишем простые функции для возведения числа в квадрат и куб:
CoffeeScript | JavaScript |
---|---|
square = (x) -> x * x
cube = (x) ->
square(x) * x |
(function() {
var cube, square;
square = function(x) {
return x * x;
};
cube = function(x) {
return square(x) * x;
};
}).call(this); |
Объявление всех локальных переменных (в данном случае - имена функций, var cube, square) выносится в начало анонимной функции-ограничителя. Это помогает избежать распространенной ошибки, когда переменная становится глобальной из-за того, что программист забыл добавить объявление var. В то же время, объявленная на верхнем уровне вложенности переменная становится видна на более низких уровнях и может быть случайно изменена. Ключевое слово JavaScript function заменяется стрелкой ->. Ключевое слово return указывать необязательно - оно добавляется автоматически к последнему выражению в функции. Блоки формируются не фигурными скобками, а отступами, как в Python.
Условные операторы
CoffeeScript может компилировать условия if в выражения JavaScript, при возможности используя тернарный оператор, и в других случаях обертку из скобок. В CoffeeScript нет явного тернарного оператора - вместо этого допускается использовать обычное условие if в одну строку.
CoffeeScript | JavaScript |
---|---|
mood = greatlyImproved if singing
if happy and knowsIt
clapsHands()
chaChaCha()
else
showIt()
date = if friday then sue else jill |
var date, mood;
if (singing) {
mood = greatlyImproved;
}
if (happy && knowsIt) {
clapsHands();
chaChaCha();
} else {
showIt();
}
date = friday ? sue : jill; |
Форматные строки
CoffeeScript позволяет форматировать строки, указывая имена переменных в конструкции #{имя}:
CoffeeScript | JavaScript |
---|---|
for i in [0..5]
console.log "Hello #{i}" |
(function() {
var i;
for (i = 0; i <= 5; i++) {
console.log("Hello " + i);
}
}).call(this); |
Параметры по умолчанию
CoffeeScript | JavaScript |
---|---|
fill = (container, liquid = "coffee") ->
"Filling the #{container} with #{liquid}..." |
var fill;
fill = function(container, liquid) {
if (liquid == null) {
liquid = "coffee";
}
return "Filling the " + container + " with " + liquid + "...";
}; |
Реализация на JavaScript сводится к проверке параметра, в случае равенства null или undefined параметру присваивается значение по умолчанию.
Операторы сравнения
В JavaScript оператор == зачастую может вести себя совершенно не так, как ожидает того программист. Безопаснее использовать === , поэтому CoffeeScript автоматически преобразует все операторы == в === . Тем не менее, возможна ситуация, когда потребуется использовать именно оператор == : к примеру, при проверке на существование (existence) значения переменной.
CoffeeScript | JavaScript |
---|---|
alert "I knew it!" if elvis? |
if (typeof elvis ! == "undefined" && elvis ! == null) {
alert("I knew it!");
} |
Оператор ? позволяет проверять неравенство одновременно двум значениям: null и undefined.
Циклы и генераторы массивов
Низкоуровневые циклы в CoffeeScript реализуются посредством while. Основное отличие от JavaScript в том, что цикл while может быть использован как выражение, возвращая значение, содержащее результат каждой итерации в цикле. Для удобочитаемости, ключевое слово until эквивалентно while not, а loop соответствует while true.
CoffeeScript | JavaScript |
---|---|
if this.studyingEconomics
buy() while supply > demand
sell() until supply > demand |
if (this.studyingEconomics) {
while (supply > demand) {
buy();
}
while (!(supply > demand)) {
sell();
}
} |
Генерация массивов (также "списковое включение", list comprehension) - это способ компактного описания операций обработки списков и массивов в языках высокого уровня. В этом случае новый список формируется путём применения к уже существующему списку некоторой последовательности операций. Наиболее часто в CoffeeScript используются генераторы массивов, которые компилируются в стандартные циклы for. В отличие от циклов в JavaScript, генераторы массивов - это выражения, и они могут возвращать значения и присваиваться. Генераторы в состоянии обрабатывать большую часть случаев, где можно использовать циклы each/forEach, map и select/filter.
CoffeeScript | JavaScript |
---|---|
cubes = (math.cube num for num in list) |
cubes = (function() {
var i, len, results;
results = [];
for (i = 0, len = list.length; i < len; i++) {
num = list[i];
results.push(math.cube(num));
}
return results;
})(); |
Для определения шага цикла можно использовать ключевое слово by, например: evens = (x for x in [0..10] by 2). Генераторы также могут быть использованы для перебора свойств и значений объекта. Используя ключевое слово of можно обращаться к свойствам объекта:
yearsOld = max: 10, ida: 9, tim: 11
ages = for child, age of yearsOld
Срезы массивов
Для работы с фрагментами массивов (срезами, slices) можно использовать диапазоны, определяемые двумя точками (..) . Так, диапазон arr[3..6], включает в себя 3, 4, 5 и 6 элемент массива arr. В диапазоне с троеточием arr[3...6] будет опущен последний элемент: 3, 4, 5. Некоторые индексы имеют значения по умолчанию: опущенный первый индекс по умолчанию имеет нулевое значение, а опущенный второй индекс по умолчанию указывает на размер массива. Срезы можно использовать также и для "блоковой" замены сразу нескольких элементов массива.
CoffeeScript | JavaScript |
---|---|
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
start = numbers[0..2]
middle = numbers[3...6]
end = numbers[6..]
copy = numbers[..]
numbers[3..6] = [-3, -4, -5, -6] |
var copy, end, middle, numbers, start, _ref;
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
start = numbers.slice(0, 3);
middle = numbers.slice(3, 6);
end = numbers.slice(6);
copy = numbers.slice(0);
[].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref; |
Встроенный JavaScript
CoffeeScript допускает использование фрагментов чистого JavaScript в коде. Для этого фрагмент JS-кода необходимо заключить в обратные кавычки.
CoffeeScript | JavaScript |
---|---|
hi = `function() {
return [document.title, "Hello JavaScript"].join(": ");
}` |
var hi;
hi = function() {
return [document.title, "Hello JavaScript"].join(": ");
}; |
Использование классов
Один из главных недостатков JavaScript заключается в его "нестандартном" стиле объектно-ориентированного программирования. В подавляющем большинстве случаев применяется ООП на основе классов, в JavaScript же объекты часто используются просто как коллекции. Кроме этого присутствует аж два способа описания классов - функциональный и прототипный. Кроме того, существует большое количество различных библиотек, предоставляющих программистам способы "традиционного" задания классов. Эти библиотеки могут значительно отличаться друг от друга, внося дополнительную неразбериху.
CoffeeScript предоставляет основную структуру class, которая позволяет задать имя класса, его суперкласс, присваивать прототипные свойства и определить конструктор.
class Animal
constructor: (@name) ->
move: (meters) ->
alert @name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
class Horse extends Animal
move: ->
alert "Galloping..."
super 45
sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"
sam.move()
tom.move()
Оператор extends используется для создания цепочки наследований между классами; оператор :: позволяет обращаться к объектам прототипа, а вызов super() конвертируется в вызов метода класса-предка с тем же именем.
Запись @name в параметрах конструктора - это сокращение, которое автоматически определяет свойство name и присваивает ему значение, передаваемое в конструкторе. В методе запись @name - сокращение от this.name.
ISSN 2542-0356
Следуй за Полисом
Оставайся в курсе последних событий
Лицензия
Если не указано иное, содержание этой страницы доступно по лицензии Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0, а примеры кода – по лицензии Apache 2.0. Подробнее см. Условия использования.