Поговорим про ES 6
19 июня 2014 года интернет-сообщество JS User Group Dnipro провело очередную JavaScript мини-конференцию при поддержке компании Maxymiser, эксперта в области персонализации и оптимизации онлайн бизнеса.
Основная цель мини конференций от JS User Group Dnipro — это расширение профессиональных связей между разработчиками и информирование их об актуальных тенденциях в сфере JavaScript. А кулуарный формат мини-конференции создает максимально комфортную обстановку для общения.
Организаторы стремятся приглашать продвинутых JS специалистов, которые могут поделиться «живым» опытом, приветствуют практические вопросы и готовы предоставить профессиональную консультацию участникам конференции.
Ярким примером такого спикера является Дмитрий Подгорный, фронтендщик и ментор, преподаватель Maxymiser Academy, который на прошлой мини конференции(от 15 марта 2014 года) представил доклад «Что нового в ES6 Harmony».
Мы предлагаем Вам познакомиться с подробной стенограммой доклада.
Поговорим про ES6
Дмитрий Подгорный
Изменения, которые нас ожидают в грядущем стандарте ES6, радикальны по сравнению с теми изменениями, которые мы наблюдали при переходе с ES3 на ES5. ES6 это не просто добавление нескольких методов, это введение новых парадигм и изменение старых. Я считаю, что программистам нужно подготовиться заранее и представлять о том, что нас ждет в будущем. Да и просто иметь представление о происходящем.
Допустим, вы предпринимаете решения по поводу того, какой язык использовать для клиентской части начинаемого проекта. Вы выбираете между CoffeeScript, Dart, Typescript и другими языками, которые транслируются в JS. И возможно, набор требований, что вы выдвигаете к языку, покрывается возможностями ES6. Сегодня существует транслятор кода из ES6 в ES5, а завтра тот же самый код без трансляции запускается во всех браузерах.
На данный момент к статус стандарта — черновик, над стандартом работает специальная группа, группа работает в открытую, можно последить за перепиской и обсуждением. У ребят из этой группы есть конкретные цели: сделать JS удобным для написания модульных программ, библиотек и больших приложений. Изменения коснутся изолирования данных, добавится синтаксический сахар, новые типы данных, модули.
Для того, чтобы потрогать es6 вы можете воспользоваться FireFox, из браузеров он один из тех, который лучше других поддерживает текущий драфт стандарта, плюс есть трансляторы такие как (traceur) от Google, или on-line песочницей, которой вы «скармливаете» es6 код и он вам выдает результат выполнения кода.
Теперь о новшествах.
В es5 видимость переменных ограничена лексической областью. Этот факт удивляет многих новичков, уже имеющих опыт программирования на других языках. В es6 предусмотрена возможность создания переменных в блочных областях видимости. Блоки можно задавать явно конструкцией из фигурных скобочек,
let foo = true; { let foo = false; console.log(foo); // false } console.log(foo); // true
а также блок видимости создается неявно при инициализации циклов.
for (let i = 0; i < document.links.length; i += 1) console.log(document.links[i], i); console.log(i); // ReferenceError
Введение блочной области видимости — удачный ход, как для новичков js, так и для опытных программистов. Первым будет проще переходить с других языков (а по опросам, js для многих является вторым рабочим языком), а вторым не нужно будет ломать копья, приходя к договоренностям: объявлять все переменные при входе в лексический контекст, или прямо перед использованием.
У функции можно будет задавать значение параметров по умолчанию при определении функции. По сути это является «синтаксическим cахаром», если мы раньше использовали лень оператора «или»,
function rectangle(x, y) { x = x || 10; y = y || x; }
то сегодня можно описать параметры по умолчанию прямо при объявлении функции:
function rectangle(x=10, y=x) { // body }
Это введение даст возможность видеть какой параметр имеет значение по умолчанию, без необходимости читать весь код функции, ну и плюс не известно в каком месте кода будет описано присвоение параметра по умолчанию, потому, что человек, который пишет код, может это сделать в неожиданном месте, что усложнит в общем понимание программы.
Также превосходное нововведение — это rest — параметры: возможность собрать все параметры после определенного в массив (что важно — именно в массив). По сути это тоже «синтаксический cахар», сегодня в es5 мы используем slice на объекте arguments, что в принципе дает тот же результат.
function callLast(fn) { let last = Array.prototype.slice.call(arguments, 1) return function () { let first = Array.prototype.slice.call(arguments, 0) return fn.apply(this, first.concat(last)) } }
Код получается достаточно мусорным, и неоднозначным (снова для тех, кто с js знаком «по наслышке»). Но теперь можно будет использовать rest—параметры.
function callLast(fn, ...restArgs) { return function (...args) { return fn.apply(this, args.concat(restArgs)) } }
Spread оператор, проще говоря — позиционная подстановка элементов последовательности, например массива или массивоподобного объекта. Например, можно подставить все элементы массива внутрь «литерала» вновь создаваемого массива.
let links = [...document.links];
Либо использовать spread оператор, для того, чтобы передать массив в качестве последовательных аргументов в функцию (в конструктор тоже).
var items = [2,6,3,9,7,3,5] // ES5 var max = Math.max.apply(Math, items) // ES6 var max = Math.max(...items)
Кстати, spread работает с любыми итерируемыми последовательностями (array, map, set, и др).
Возвращение множественных значений из функции стало легче и приятнее. Сегодня работа с множественными возвращаемыми значениями — синтаксическая боль:
function getPosition() { return [x, y] } var position = getPosition() var x = position[0] var y = position[1]
Завтра же нас ждет чистое будущее
function getPosition() { return [x, y] } var [x, y] = getPosition()
Операция деструктуризации не строгая: количество связываемых переменных и значений массива не обязано совпадать. «Разрушать» можно не только массивы, но и объекты. При этом название переменных должно совпадать с названием ключей.
document.body.onclick = function (event) { let {clientX, clientY} = event console.log(clientX, clientY) }
Появился такой тип данных, как set — коллекция уникальных значений. При попытке добавить в set значения, которые в нем уже есть, ничего не произойдет: не выбросится иключение и в set останется тот же набор значений, который был до добавления. Плюс set можно комбинировать со spread оператором и превращать set в массив.
var arr = [1,2,5,4,2,1] var unique = [...Set(arr)] console.log(unique) // [1,2,5,4]
WeakMap это хранилище ключ-значение, где в качестве ключа используется объект, а в качестве значения может выступать любой тип данных. WeakMap интересен с тем, как с ним работает сборщик мусора (Garbage collector). Если не осталось ни одной ссылки на объект, который использован в WeakMap, то память, выделенная под этот объект, буде высвобождена. Такое поведение сборщика мусора позволяет использовать в качестве ключей дом-узлы, не боясь , что после удаления DOM дерева, ссылки на узлы не позволят память быть высвобожденной.
Итераторы — специальный интерфейс, с помощью которого можно настроить то, каким образом будет происходить итерация по объекту. Итератор состоит из нескольких нововведений: во-первых новый вид цикла for...of, а во—вторых возможность настраивать итератор для своих объектов.
Цикл for...of хорошо работает в комбинации с новым типом данных Map и деструктуризацией.
var m = Map() m.set('foo', 'bar') m.set('bar', 'baz') for (let [key, value] of m) { console.log(key, value) }
А так же с массивоподобными объектами
for (let link of document.links) { console.log(link) }
Для своего типа данных указать каким образом будет происходить итерация по объекту с помощью цикла for...of. For...of не итерирует по ключам объекта. Разве что можно использовать Object.keys(), для получения всех ключей объекта и уже итерировать по ним.
for...of — хороший кандидат на роль единого подхода для итерации по последовательностям.
Это такие специальные функции, которые могут прекращать свое выполнение на время, сохраняя свое состояние. Генераторы призваны упростить работу с асинхронным кодом. Библиотеке передается генератор, который yield — выбрасывает Promise объект. Когда promise вычисляется в значение, библиотека передает вычисленное значение в итератор. Пример кода — в документации task.js
Еще один из способов применения генераторов — описание потенциально бесконечных последовательностей.
function* random(size) { let i = 0 while (i < size) { i += 1 yield Math.random() } } [...random(10)] [...random(100)]
Генератор можно комбинировать spread-оператором, можно или с циклом for ...off и они прекрасно отработают. Еще один способ применения генератора — описание ленивых фильтров. Вместо того, чтобы сразу вычислять значения отфильтрованной последовательности, значения будут вычисляться по мере обращения к ним.
function* lazyFilter(filterFunc, data) { for (let item of data) { if (filterFunc(item)) { yield item } } } var funcs = lazyFilter(function (item) { return typeof item === 'function' }, [42, 'foo', NaN, 'boo', function() {}]); console.log([...funcs])
Функции с легким синтаксисом и лексическим контекстом. this внутри функции-стрелки ссылается туда же, куда и ссылался this внутри контекста, где функция была объявлена. Сегодня мы используем bind для закрепления контекста
Gallery.prototype.addHandlers = function () { this.node.onclick = (function () { if (!this.isInitialised()) { this.init() } }).bind(this) }
Завтра необходимость в лишнем шуме в коде отпадет:
Gallery.prototype.addHandlers = function () { this.node.onclick = () => { if (!this.isInitialised()) { this.init() } } }
Функции-стрелки легко и приятно передавать в качестве аргументов для сортировки или в map
var arr = ['lorem', 'ipsum', 'dolor', 'sit'] var len = arr.map( w => w.length ) console.log(len) // [5, 5, 5, 3]
Заключение
О чем я не упомянул: классы, у которых механизм наследования построен на на цепочке прототипов, вот только синтаксис создания этой цепочки будет поход на синтаксис создания классов в других языках. Поддержка модулей на уровне языка. Модули могут быть локальными (на уровне браузера), и подгружаемыми модули, или определенными на странцие сайта. А так же генераторы массивов, шаблонные строки (квази литералс или template strings), Object.observe (в планах на es7, но хром уже реализует), функции, возаращающие Promise. Держите руку на пульсе: нас ждут большие изменения.
16 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів