CoffeeScript

Скриптовый язык программирования Из Википедии, свободной энциклопедии

CoffeeScript — язык программирования, транслируемый в 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 не является широко используемым, из за чего сложнее искать источники информации по нему и кооперировать с другими разработчиками

Синтаксис

Суммиров вкратце
Перспектива

Особенности

  1. отсутствие точек с запятой (при этом, в самом JavaScript использование точек с запятой не обязательно, хоть и рекомендуется)
  2. фигурные скобки {} заменены табуляцией

Комментарии

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

CoffeeScript:

# однострочный комментарий

###
    многострочный
    комментарий
###

JavaScript:

// однострочный комментарий

/*
  многострочный
  комментарий
*/

Пробелы

Подобно языку Python, CoffeeScript использует табуляции для обозначения блоков кода.

Переменные

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

CoffeeScript:

myVariable = "test"

JavaScript:

let myVariable = "test";

Функции

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

CoffeeScript:

func = -> "bar"

func = ->
  # An extra line
  "bar"

JavaScript:

function func() {
  return "bar";
}

// другой вариант (с использованием стрелочной функции)
let func = () => "bar";

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

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

CoffeeScript:

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

JavaScript:

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

// другой вариант
let times = (a = 1, b) => a * b;

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

CoffeeScript:

a = "Howdy!"

alert a
# Equivalent to:
alert(a)

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

JavaScript:

let a = "Howdy!";

alert(a);

alert(inspect(a));

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

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


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

Объектные литералы задаются точно так же, как и в 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:

let object1 = {
  one: 1,
  two: 2
}
let object2 = {
  one: 1,
  two: 2
}
let object3 = {
  one: 1,
  two: 2
}

User.create({
  name: "John Smith"
});

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

CoffeeScript:

array1 = [1, 2, 3]

array2 = [
  1
  2
  3
]

array3 = [1,2,3,]

JavaScript:

let array1 = [1, 2, 3];

let array2 = [
  1,
  2,
  3
];

let array3 = [1, 2, 3,];

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

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

CoffeeScript:

if true == true
  alert "We're ok"

if true != true then alert "Panic"

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

JavaScript:

if (true === true) {
  alert("We're ok");
}
if (true !== true) {
  alert("Panic");
}

if (1 > 0) {
  alert("Ok");
} else {
  alert("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 alert "Panic"

unless true
  alert "Panic"

JavaScript:

if (!true) {
  alert("Panic");
}

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

CoffeeScript:

if true is 1
  alert "Type coercion fail!"

JavaScript:

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

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

CoffeeScript поддерживает интерполяцию строк (то есть вставка значения переменной в качестве текста внутрь строки): делается это посредством использования #{} внутри строки, заключённой в двойные кавычки. На момент выхода CoffeeScript у JavaScript не было такой возможности, однако с выходом стандарта ECMAScript 6 в 2015 году возможность так делать появилась и в JavaScript: для этого строка должна заключаться в специальные кавычки `` (машинописный обратный апостроф), а вставка переменных производится с использованием ${}.

CoffeeScript:

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

JavaScript:

let favouriteColor = "Blue. No, yel...";
let question = `Bridgekeeper: What... is your favourite color?
                Galahad: ${favouriteColor}
                Bridgekeeper: Wrong!
`;


Массивы

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

CoffeeScript:

range = [1..5]

JavaScript:

let 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:

let firstTwo = ["one", "two", "three"].slice(0, 2);

let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
numbers = [...numbers.slice(0, 3), -3, -4, -5, ...numbers.slice(6)];

let my = "my string".slice(0, 3);

Для проверки наличия значения внутри массива в JavaScript можно использовать метод .includes(). В CoffeeScript для этого есть специальный оператор in.

CoffeeScript:

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

JavaScript:

let words = ["rattled", "roudy", "rebbles", "ranks"];
if (words.includes("ranks")) {
  alert("Stop wagging me");
}

Классы

Суммиров вкратце
Перспектива

Ключевое слово class было добавлено в JavaScript в стандарте ECMAScript 6. При этом, JavaScript и до этого поддерживал классы (за счёт использования прототипов), а само ключевое слово class является синтаксическим сахаром:

class Person {
  constructor(name) {
    this.name = name;
  }
  
  say(phrase) {
    return `${this.name} говорит ${phrase}`;
  }
}

// Данный код полностью эквивалентен следующему коду:

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

Person.prototype.say = function(phrase) {
  return this.name + " говорит " + phrase;
}

Далее для JavaScript-кода в данном разделе будет использоваться синтаксис с использованием class.

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

CoffeeScript:

class Animal
  constructor: (@name) ->

JavaScript:

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

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

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

CoffeeScript:

class Animal
  price: 5

  sell: (customer) ->

animal = new Animal
animal.sell(new Customer)

JavaScript:

class Animal {
  price = 5;
  
  sell(customer) {}
}

let animal = new Animal();
animal.sell(new Customer());

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

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

CoffeeScript:

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

Animal.find_("Parrot")

JavaScript:

class Animal {
  static find_(name) {}
  static age_(age) {}
}

Animal.find_("Parrot");

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

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

CoffeeScript:

class Animal
  constructor: (@name) ->

  alive: ->
    false

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

  dead: ->
    not @alive()

JavaScript:

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  alive() {
    return false;
  }
}

class Parrot extends Animal {
  constructor() {
    super("Parrot");
  }
  
  dead() {
    return !this.alive();
  }
}

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

Идиомы

Суммиров вкратце
Перспектива

Each

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

CoffeeScript:

myFunction(item) for item in array

JavaScript:

// вариант с forEach
array.forEach(myFunction);

// вариант с циклом
for (let i = 0; i < array.length; i++) {
  let item = array[i];
  myFunction(item);
}

Includes

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

CoffeeScript:

string = "a long test string"
included = "test" in string

JavaScript:

let string = "a long test string";
let included = string.includes("test");

Итерации

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

CoffeeScript:

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

JavaScript:

let object = {
  one: 1,
  two: 2
};

for (let key in object) {
  let 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(...[14, 35, -7, 46, 98]);
Math.min(...[14, 35, -7, 46, 98]);
// (здесь используется оператор ..., позволяющий разбивать массивы на отдельные значения и напрямую передавать их в функции как параметры)

// второй способ:
Math.max.apply(null, [14, 35, -7, 46, 98]);
Math.min.apply(null, [14, 35, -7, 46, 98]);

And/or

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

CoffeeScript:

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

JavaScript:

let string = "migrating coconuts";
string === string;
string === string;

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

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

CoffeeScript:

# Use local alias
$ = jQuery

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

JavaScript:

let $ = 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:

const say = 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:

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

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

let 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();


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

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

Компилятор

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

См. также

Примечания

Литература

Ссылки

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.