Статьи

Качаем с CoffeeScript

Хотя CoffeeScript — это новый язык, вы выучите его очень быстро. Вы должны, так как это всего лишь JavaScript, щеголяющий с какой-то роскошной одеждой, в конце концов. Он читается как Ruby или Python, но компилируется в чистый, не пушистый JavaScript. Сегодня мы рассмотрим, почему все говорят о CoffeeScript.


С появлением мощных движков JavaScript, таких как V8, JavaScript потерял свое клеймо позорного инструмента для взаимодействия с несовершеннолетними и превратился в мощный двигатель. Он даже перепрыгнул с клиентских приложений на серверную, например, node.js. Тот факт, что он придерживается довольно изящной идеологии, основанной на прототипах, тоже не повредит. Нет сомнений в том, что JavaScript действительно является критическим языком сейчас и в обозримом будущем.

Но я всегда чувствовал, что сам синтаксис немного глуповат. После работы с сочетанием Ruby и Python в течение последних нескольких лет я обнаружил, что многоточечный синтаксис JavaScript, заключенный в скобки, является утомительным. И из того, что я могу собрать, я не одинок в своих чувствах. Вот где CoffeeScript приходит на помощь!


CoffeeScript компилируется в сырой JS.

CoffeeScript по сути является просто синтаксическим переписыванием JavaScript. Сам основной язык остается тем же, с небольшими семантическими улучшениями. Синтаксис изменен, смоделирован после Python и Ruby.

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

Это может показаться инопланетной концепцией, но под эгидой веб-разработки мы уже видели нашу справедливую долю этой идеологии. HAML — это всего лишь новый способ написания HTML, в то время как SASS делает то же самое для CSS. Все они очищают структуру и синтаксис своих языков, облегчая работу с ними и тем самым повышая нашу производительность.


Вы, наверное, задаетесь вопросом, как выглядит сам код, так что вот быстрый взгляд:

1
2
3
4
5
6
7
8
index = (list, target) ->
  [low, high] = [0, list.length]
  while low < high
    mid = (low + high) >> 1
    val = list[mid]
    return mid if val is target
    if val < target then low = mid + 1 else high = mid
  return -1

Это быстрая реализация бинарного поиска. Не пытайтесь разобрать сам код прямо сейчас. Просто попробуйте ознакомиться с синтаксисом.

Ниже приведен код JavaScript, который генерирует CoffeeScript:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
var index;
index = function(list, target) {
  var high, low, mid, val, _ref;
  _ref = [0, list.length], low = _ref[0], high = _ref[1];
  while (low < high) {
    mid = (low + high) >> 1;
    val = list[mid];
    if (val === target) {
      return mid;
    }
    if (val < target) {
      low = mid + 1;
    } else {
      high = mid;
    }
  }
  return -1;
};

Вот несколько быстрых преимуществ и недостатков использования CoffeeScript. Это ни в коем случае не является исчерпывающим, но я думаю, что этого достаточно, чтобы получить краткий обзор системы.

  • Пробел в стиле Python
  • Легкий синтаксис в стиле Ruby
  • Краткие объявления функций
  • JSLint утвержден
  • Наследование на основе классов

Есть, конечно, множество других моментов, включая семантические и синтаксические улучшения.

  • Небольшая кривая обучения
  • Развертывание, в зависимости от вашего маршрута, может быть рутиной
  • Вам понадобятся базовые знания JS для целей отладки. Вы не можете напрямую начать здесь, естественно.

Официальные методы для начала включают утилиту командной строки, которая запускается под node.js и просто загружает исходный код и устанавливает его. Ничего особенного, чтобы направлять здесь. Получите утилиту node.js и используйте npm install coffee-script [или для исходного кода bin/cake install ], чтобы установить и начать работу.

Ситуация с Windows немного сложнее. Не существует прямого способа получить node.js или исходный код, установленный в Windows [вне Cygwin]. Никогда не волнуйтесь, хотя. Многие предприимчивые люди написали компиляторы, которые изначально работают на Windows. Я включил несколько ниже:

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

После этого мы рассмотрим несколько вещей, которые покажут вам, как CoffeeScript облегчает использование JavaScript!


Первое, что вам нужно знать, — это то, как CoffeeScript эффективно использует пробелы для упрощения синтаксиса. Люди с опытом работы с Python найдут это тривиальным, но для остальных вот краткое объяснение.

Во-первых, вам не нужно заканчивать каждую строку точкой с запятой. Окончание строки автоматически интерпретируется как конец этого оператора. Например, это ..

1
2
numbers = [0, 1, 2, 3]
name = «NetTuts+»

.. компилируется до этого:

1
2
3
var name, numbers;
numbers = [0, 1, 2, 3];
name = «NetTuts+»;

Далее вы будете рады узнать, что вы можете покончить с фигурными скобками. Эти многочисленные скобки для открытия и закрытия блока? Все вышло В CoffeeScript вы используете отступ Python-esque для обозначения начала и конца блока.

CoffeeScript не требует лишних скобок или фигурных скобок.

Вот быстрый пример. Не обращайте внимания на все, кроме отступа на данный момент. Остальное мы доберемся чуть позже:

1
2
if chasedByCylons
 runForYourLife()

.. компилируется до

1
2
3
if (chasedByCylons) {
  runForYourLife();
}

Если вы все еще немного сбиты с толку, не волнуйтесь. Синтаксис станет более понятным, как только мы лучше узнаем язык.


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

Во-первых, операторы сравнения:

  • is карты на ===
  • isnt компилируется в !==
  • == и != компилировать в === и !== соответственно [В качестве лучшей практики]

Давайте посмотрим их в действии быстро.

1
2
3
4
5
if pant is onFire
 lookForWater()
 
if game isnt good
 badMouth();

.. который компилируется в ..

1
2
3
4
5
6
if (pant === onFire) {
  lookForWater();
}
if (game !== good) {
  badMouth();
}

Довольно легко читать, нет? Теперь о том, как отображаются логические операторы.

  • and сопоставляет с &&
  • or является псевдонимом для ||
  • not компилируется !

Опираясь на наш предыдущий код:

1
2
3
4
5
if pant is onFire and not aDream
 lookForWater()
 
if game isnt good or haughtyDevs
 badMouth();

.. который компилируется в ..

1
2
3
4
5
6
if (pant === onFire && !aDream) {
  lookForWater();
}
if (game !== good || haughtyDevs) {
  badMouth();
}

Как вы уже видели выше, базовая конструкция if/else ведет себя так же, как в обычном JavaScript, без скобок и фигурных скобок. Мы рассмотрим некоторые варианты ниже.

01
02
03
04
05
06
07
08
09
10
11
12
if tired and bored
 sleep()
else
 jog()
  
// Raw JS below
 
if (tired && bored) {
  sleep();
} else {
  jog();
}

А вот как обрабатывается троичный оператор:

1
2
3
4
5
activity = if sunday then isChilling else isWorking
  
// Raw JS below
 
activity = sunday ?

Дополнительное семантическое улучшение — с помощью ключевого слова exc. Это действует как полная противоположность if .

1
2
3
keepRunning() unless tired
 
keepWorking unless focus is extremelyLow

И скомпилированный JavaScript …

1
2
3
4
5
6
if (!tired) {
  keepRunning();
}
if (focus !== extremelyLow) {
  keepWorking;
}

Операторы Switch могут быть немного тупыми в JavaScript. CoffeeScript предоставляет интуитивно понятную оболочку для этой конструкции.

Как и ожидалось, он начинается с ключевого слова switch , за которым следует переменная, значение которой мы проверяем. Каждому случаю или возможному значению предшествует ключевое слово when за которым следуют операторы для выполнения, если это совпадение.

Нет необходимости добавлять оператор break в конце каждого оператора case: CoffeeScript делает это автоматически для вас.

01
02
03
04
05
06
07
08
09
10
switch time
 when 6.00
  wakeUp()
  jotDownList()
 when 9.00 then startWorking()
 when 13.00 then eat()
 when 23.00
  finishUpWork()
  sleep()
 else doNothing()

Синтаксис должен быть достаточно понятным, если вы уже знаете его эквивалент в JavaScript. Единственное, на что следует обратить внимание — это использование ключевого слова then . Он используется для отделения условия от выражения без начала новой строки. Вы можете использовать их для других условных операторов, а также для циклов.

Вот JS, который CoffeeScript генерирует для вас:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
switch (time) {
  case 6.00:
    wakeUp();
    jotDownList();
    break;
  case 9.00:
    startWorking();
    break;
  case 13.00:
    eat();
    break;
  case 23.00:
    finishUpWork();
    sleep();
    break;
  default:
    doNothing();
}

Циклы — еще одна важная конструкция для вашего типичного кода JavaScript. Будь то циклическое перемещение по числам в массиве или узлам в DOM, вам всегда нужно проходить по коллекциям.

CoffeeScript предоставляет очень гибкий цикл while, который можно изменить, чтобы он функционировал как универсальный цикл for или do-while while.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
while work > time then freakOut()
 
while time > work
  relax()
  mozyAround()
 
// Raw JS
 
while (work > time) {
  freakOut();
}
while (time > work) {
  relax();
  mozyAround();
}

until еще одно семантическое улучшение и эквивалентно, while not. Быстрый пример ниже:

1
2
3
4
5
6
7
workOut() until energy < exhaustion
 
// Raw JS
 
while (!(energy < exhaustion)) {
  workOut();
}

Зацикливание массивов довольно просто. Вам нужно будет использовать конструкцию for..in чтобы пройти через массив. Позвольте мне показать вам, как:

1
2
3
sites = [‘CodeCanyon’,’ThemeForest’,’ActiveDen’]
for site in sites
 alert site

Если вы предпочитаете, чтобы операторы были в одной строке:

1
2
sites = [‘CodeCanyon’,’ThemeForest’,’ActiveDen’]
alert site for site in sites

CoffeeScripts компилирует их в базовые циклы, например, так. Обратите внимание, что в соответствии с рекомендациями, длина массива заранее кэшируется.

1
2
3
4
5
6
var site, sites, _i, _len;
sites = [‘CodeCanyon’, ‘ThemeForest’, ‘ActiveDen’];
for (_i = 0, _len = sites.length; _i < _len; _i++) {
  site = sites[_i];
  alert(site);
}

Перебирать ассоциированные массивы [или хэши, словари или пары ключ-значение] так же просто, как с ключевым словом of .

1
2
3
4
managers = ‘CodeCanyon’: ‘Jeffrey Way’, ‘ThemeForest’: ‘Mark Brodhuber’, ‘ActiveDen’: ‘Lance Snider’
 
for site, manager of managers
  alert manager + » manages » + site

Как и ожидалось, вышесказанное компилируется в базовый цикл for, как показано ниже:

01
02
03
04
05
06
07
08
09
10
var manager, managers, site;
managers = {
  ‘CodeCanyon’: ‘Jeffrey Way’,
  ‘ThemeForest’: ‘Mark Brodhuber’,
  ‘ActiveDen’: ‘Lance Snider’
};
for (site in managers) {
  manager = managers[site];
  alert(manager + » manages » + site);
}

Создавать и использовать функции очень легко под CoffeeScript. Чтобы определить функцию, вы перечисляете параметры, которые она принимает, а затем переходите к телу функции. Вот, позвольте мне показать вам, как:

1
2
3
4
playing = (console, game = «Mass Effect») ->
  alert «Playing #{game} on my #{console}.»
 
playing ‘Xbox 360’, ‘New Vegas’

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

Вызов функции также прост. В скобках нет необходимости: передавайте параметры один за другим.

Как всегда, вот сгенерированный код для вашей справки:

1
2
3
4
5
6
7
8
var playing;
playing = function(console, game) {
  if (game == null) {
    game = «Mass Effect»;
  }
  return alert(«Playing » + game + » on my » + console + «.»);
};
playing(‘Xbox 360’, ‘New Vegas’);

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

Вы можете добавить необработанный JS в свой код, обернув его серьезными акцентами, также известными как обратная кавычка или обратный удар. Все переданное таким образом будет полностью не затронуто компилятором CoffeeScript.

01
02
03
04
05
06
07
08
09
10
rawJS = `function() {
  return someSuperComplexThingie;
}`
 
// which nets you
 
var rawJS;
rawJS = function() {
  return someSuperComplexThingie;
};

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

Поэтому вместо того, чтобы писать это:

01
02
03
04
05
06
07
08
09
10
11
$(document).ready(function() {
 elemCollection = $(‘.collection’);
  for (i=0; i<=elemCollection.length;i++)
  {
    item = elemCollection[i];
   // check for some random property here.
   colortoAdd = item.hasProperty()?
   // I’m quite aware there are better ways to do this
   $(item).css (‘background-color’, colortoAdd);
  }
});

… ты бы написал ..

1
2
3
4
5
$(document).ready ->
    elemCollection = $(‘.collection’)
    for item in elemCollection
      colortoAdd = if item.hasProperty() then yesColor else noColor
      $(item).css ‘background-color’, colortoAdd

И мы подошли к концу. Я не охватил ряд тем более высокого уровня, например, классов, потому что они выходят далеко за рамки вводной статьи. Ищите некоторые продвинутые учебники CoffeeScript в будущем!

Я думаю, что CoffeeScript изменил способ написания JavaScript, и, прочитав это, я надеюсь, что он изменил и ваш. Вопросов? Хорошие вещи, чтобы сказать? Критицизмы? Нажмите на раздел комментариев и оставьте мне комментарий. Приятного кодирования и большое спасибо за чтение!