CoffeeScript: различия между версиями
[отпатрулированная версия] | [непроверенная версия] |
Вставка пропущенного предлога |
→Статичные свойства: орфография |
||
(не показаны 32 промежуточные версии 24 участников) | |||
Строка 1: | Строка 1: | ||
{{Язык программирования |
{{Язык программирования |
||
| name = CoffeeScript |
|||
| logo = CoffeeScript-logo.svg |
|||
| semantics = |
|||
| paradigm = [[Мультипарадигмальный язык программирования|мультипарадигмальный]]: |
|||
|paradigm = [[Объектно-ориентированное программирование|объектно-ориентированный]], [[Императивное программирование|императивный]], [[Функциональное программирование|функциональный]], [[Аспектно-ориентированное программирование|аспектно-ориентированный]], [[Прототипное программирование|прототипный]] |
|||
[[Объектно-ориентированное программирование|объектно-ориентированный]], [[Императивное программирование|императивный]], [[Функциональное программирование|функциональный]], [[Аспектно-ориентированное программирование|аспектно-ориентированный]], [[Прототипное программирование|прототипный]] |
|||
|class = |
|||
| class = |
|||
|latest_preview_version = |
|||
| последняя версия = 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_date = |
|||
| дата выпуска последней версии = {{start date and age|2022|04|24}} |
|||
|typing = |
|||
| latest_preview_version = |
|||
|implementations = |
|||
| latest_preview_date = |
|||
|dialects = |
|||
| typing = |
|||
|influenced_by = [[JavaScript]], [[Python]], [[Ruby]], [[Haskell]], [[Erlang]] |
|||
| implementations = |
|||
|influenced = [[MoonScript]], [[LiveScript]] |
|||
| dialects = |
|||
|designer = [[Джереми Ашкенас]]}} |
|||
| influenced_by = [[JavaScript]], [[Python]], [[Ruby]], [[Haskell]], [[Erlang]] |
|||
| 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> |
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]. |
||
Строка 21: | Строка 25: | ||
Создателем языка является [[Ашкенас, Джереми|Джереми Ашкенас]]. |
Создателем языка является [[Ашкенас, Джереми|Джереми Ашкенас]]. |
||
Изначально компилятор был написан на [[Ruby]], но в версии 0.5, которая вышла [[21 февраля]] [[2010 |
Изначально компилятор был написан на [[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 coffescript», позволяющий выполнять программы на нём 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> |
||
JavaScript: |
JavaScript: |
||
<source lang="javascript"> |
<source lang="javascript"> |
||
let age = 2, |
|||
male = true, |
male = true, |
||
name = "Матвей"; |
name = "Матвей"; |
||
Строка 48: | Строка 591: | ||
=== Функции === |
=== Функции === |
||
CoffeeScript: |
CoffeeScript: |
||
<source lang="ruby"> |
<source lang="ruby"> |
||
Строка 54: | Строка 596: | ||
alert speech |
alert speech |
||
say " |
say "Привет мир!" |
||
</source> |
|||
JavaScript с использованием [[ECMAScript]] 2015: |
|||
<source lang="javascript"> |
|||
const say = speech => alert(speech); |
|||
say('Привет мир!'); |
|||
</source> |
</source> |
||
Строка 62: | Строка 610: | ||
alert(speech); |
alert(speech); |
||
}; |
}; |
||
say(" |
say("Привет мир!"); |
||
</source> |
</source> |
||
=== Классы и объекты === |
=== Классы и объекты === |
||
CoffeeScript: |
CoffeeScript: |
||
<source lang="coffeescript"> |
<source lang="coffeescript"> |
||
Строка 74: | Строка 621: | ||
class Baby extends Human |
class Baby extends Human |
||
say : (msg) -> alert "#{@name} говорит '#{msg}'" |
say : (msg) -> alert "#{@name} говорит '#{msg}'" |
||
sayHi : -> @say(' |
sayHi : -> @say('здравствуй!') |
||
matt = new Baby("Матвей") |
matt = new Baby("Матвей") |
||
matt.sayHi() |
matt.sayHi() |
||
</source> |
|||
JavaScript с использованием [[ECMAScript]] 2015: |
|||
<source lang="javascript"> |
|||
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(); |
|||
</source> |
</source> |
||
Строка 95: | Строка 663: | ||
}; |
}; |
||
Baby.prototype.sayHi = function(){ |
Baby.prototype.sayHi = function(){ |
||
this.say(' |
this.say('здравствуй!'); |
||
}; |
}; |
||
Baby.prototype.constructor = |
Baby.prototype.constructor = Human; |
||
var matt = new Baby("Матвей"); |
var matt = new Baby("Матвей"); |
||
Строка 117: | Строка 685: | ||
}, |
}, |
||
sayHi : function() { |
sayHi : function() { |
||
this.say(' |
this.say('здравствуй!'); |
||
} |
} |
||
}); |
}); |
||
Строка 133: | Строка 701: | ||
@hi = -> msg # динамический метод, записан в экземпляр Test |
@hi = -> msg # динамический метод, записан в экземпляр Test |
||
</source> |
</source> |
||
== Компилятор == |
|||
Интересным является тот факт, что компилятор для CoffeeScript написан на самом CoffeeScript |
|||
== См. также == |
== См. также == |
||
Строка 145: | Строка 716: | ||
== Литература == |
== Литература == |
||
* {{книга|автор=Марк Бейтс.|заглавие=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,|ссылка = |
* {{Книга|автор = Alex MacCaw|заглавие = The Little Book on CoffeeScript|ответственный = |издание = |место = |издательство = O'Reilly Media|год = 2011|страницы = |страниц = 60|isbn = 9781449321055,|ссылка = https://arcturo.github.io/library/coffeescript/|ref = MacCaw}} |
||
* [http://coffeescriptcookbook.com/ CoffeeScript Cookbook], сборник рецептов CoffeeScript от сообщества. |
* [https://archive.today/20121208174724/http://coffeescriptcookbook.com/ CoffeeScript Cookbook], сборник рецептов 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] |
|||
== Ссылки == |
== Ссылки == |
||
Строка 159: | Строка 731: | ||
* [http://cidocs.ru/coffeescript/ Перевод официальной документации] |
* [http://cidocs.ru/coffeescript/ Перевод официальной документации] |
||
* [https://groups.google.com/group/coffeescript2ru/ Русскоязычная группа по ''CoffeeScript''] |
* [https://groups.google.com/group/coffeescript2ru/ Русскоязычная группа по ''CoffeeScript''] |
||
* [ |
* [https://coffeescript2ru.github.com/ Русскоязычный сайт по ''CoffeeScript''] |
||
* [https://www.youtube.com/watch?v=OdQmfnAiDzY&list=PLwSSV-_L9sztYcaMbY2XlehMFeR8Khs0j Видеокурс (ru)] |
|||
Смежные проекты: |
Смежные проекты: |
||
Строка 169: | Строка 742: | ||
[[Категория:Семейство языков программирования JavaScript]] |
[[Категория:Семейство языков программирования JavaScript]] |
||
[[Категория:Прототипно-ориентированные языки программирования]] |
|||
[[Категория:Транспиляция]] |
Текущая версия от 12:44, 22 сентября 2024
CoffeeScript | |
---|---|
Класс языка | |
Появился в | 13 декабря 2009 |
Автор | Джереми Ашкенас |
Расширение файлов |
.coffee |
Выпуск | 2.7.0[1] (24 апреля 2022 ) |
Испытал влияние | 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 и является трудноразрешимой проблемой.
Each
[править | править код]В 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);
}
Includes
[править | править код]Проверка того, находится ли значение внутри массива, обычно выполняется с помощью функции 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);
}
Min/Max
[править | править код]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]);
And/or
[править | править код]В руководствах по стилю 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!");
});
});
Private variables
[править | править код]Ключевое слово 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
См. также
[править | править код]Примечания
[править | править код]- ↑ "2.7.0". Архивировано 23 июня 2022. Дата обращения: 23 июня 2022.
- ↑ The coffeescript Open Source Project on Open Hub: Licenses Page — 2006.
- ↑ Пример на титульной странице официального сайта . Дата обращения: 18 января 2012. Архивировано 9 июня 2017 года.
- ↑ Try CoffeeScript . coffeescript.org. Дата обращения: 4 января 2016. Архивировано 9 июня 2017 года.
- ↑ Try Ruby: learn the basics of the Ruby language in your browser. tryruby.org. Дата обращения: 4 января 2016. Архивировано 28 сентября 2011 года.
Литература
[править | править код]- Марк Бейтс. CoffeeScript. Второе дыхание JavaScript = Mark Bates. Programming in CoffeeScript. — М.: ДМК, 2012. — 312 с. — 300 экз. — ISBN 978-5-94074-842-7.
- Alex MacCaw. The Little Book on CoffeeScript. — O'Reilly Media, 2011. — 60 с. — ISBN 9781449321055,.
- CoffeeScript Cookbook, сборник рецептов CoffeeScript от сообщества.
- Smooth CoffeeScript Архивная копия от 11 июля 2011 на Wayback Machine, свободная электронная книга о CoffeeScript. Доступна в двух вариантах с исходным кодом примеров.
- Майкл Галпин. Ваша первая чашечка CoffeeScript : Часть 1. Приступаем к работе . DeveloperWorks (19 июля 2012). Дата обращения: 10 января 2016.
- Ваша первая чашечка CoffeeScript: Часть 2. Изучение языка на практических примерах (18 июля 2012). Дата обращения: 10 января 2016.
- Ваша первая чашечка CoffeeScript: Часть 3. Использование CoffeeScript на стороне клиента (20 июля 2012). Дата обращения: 10 января 2016.
- Ваша первая чашечка CoffeeScript: Часть 4. Использование CoffeeScript на стороне сервера (20 июля 2012). Дата обращения: 10 января 2016.
- Эндрю Гловер. Функциональный JavaScript с применением CoffeeScript и Node . DeveloperWorks (3 декабря 2012). Дата обращения: 10 января 2016.
- Alex MacCaw. The Little Book on CoffeeScript
Ссылки
[править | править код]- Официальный сайт CoffeeScript
- Репозиторий CoffeeScript на GitHub
- Перевод официальной документации
- Русскоязычная группа по CoffeeScript
- Русскоязычный сайт по CoffeeScript
- Видеокурс (ru)
Смежные проекты:
- Компилятор CoffeeScript для Windows
- CoffeeKup, шаблонизатор и движок для генерации HTML-кода на CoffeeScript.
- Prepros, компилирует на лету CoffeeScript. Под Windows и OSX (также компилирует LESS, Stylus, Haml, Jade, Markdown, Slim, SASS)