Поиск по метке: es6
IE8 и babel
В одном из проектов требуется на уровне ТЗ поддержка Internet Explorer 8. Спасибо, что не 7 :) Дошли руки до перевода кодовой базы на es6. Воткнул как обычно preset es2015, потестил, вроде всё работает, но дёрнул меня чёрт проверить и в старом ослике. Подохло там всё. Причём глюк настолько странный, что я невольно задвигал бровями. Перейду сразу к сути:
function init(){ console.log(1); }
var a = { init: function(){ console.log(2); } };
init();
Результат, конечно же, 1. Однако babel превратит сий код в:
"use strict";
function init() {
console.log(1);
}
var a = { init: function init() {
console.log(2);
} };
init();
Ключевое отличие ― именование метода. Теперь он тоже init. Зачем? Не ко мне вопрос. Может быть для упрощения отладки. Но с этого момента старый ишак возвращает 2. Оказывается это старый баг тогдашнего jscript-а.
Лечение: добавляем: plugins: ["transform-jscript"] к настройкам babel-я. Ну и соответственно тащим этот плагин. С этого момента babel будет генерировать вот таких вот монстров:
"use strict";
function init() {
console.log(1);
}
var a = { init: function() {
function init(){ console.log(2); }
init();
} };
init();
Очень бредово, если честно. Ведь можно было сохранить изначальный код в первозданном виде.
For-of и браузеры
Оказывается, браузеры по-разному относятся к итерированию цикла for-of. Судите сами:
for(const a of []) ; // chrome: ok, ff: syntax error
На что ругается Firefox? Говорит, что a указана, как константа, а используется как переменная. Но почему?
for(let a of [1, 2])
setTimeout(() => alert(a));
- Chrome: 1, 2
- Firefox: 2, 2
Всё просто. Chrome каждую итерацию пересоздаёт scope, а Firefox довольствуется одним. И если с const ошибка вылезет сразу (правда только в Firefox). То в случае чего-нибудь асинхронного ждите трудно-вылавливаемые баги, которые проявятся только в Firefox-е. В спеку мне лезть лень, но код генерируемый babel-ем ближе к Chrome-варианту. Кто прав?
Javascrpt ES6 и классы
Понемногу перебираюсь на JavaScript ES6 синтаксис. По мере появления его нативной поддержки в nodeJS и Chrome. ES6 таит в себе множество не очевидных вещей. Больше всего я их встретил в class-ах. Классы в ES6 это обширный набор синтаксического сахара для prototype. С ними писать код приятнее, да и сам синтаксис вынуждает подходить к этому дисциплинированнее. В этой мини-заметке я опишу пары интересных моментов:
- Синтаксис допускает только короткие имена методов;
- Тело класса описывает методы, которые будут помещены в prototype и статические методы, которые будут помещены в сам объект класса. Так вот… Таким образом вы можете поступить только с методами и generator-ми. Т.е. никаких хешей, никаких чисел, строк, регулярных выражений. Всё, что вы захотите поместить сверх методов и генераторов будет идти уже отдельными строками кода после описания класса;
- Это ограничение довольно понятно. Дескать дисциплинирует все подобные вещи определять в конструкторе и не позволяет переписывать детьми в прототипе. Но…
Почему то nodejs не поддерживает статические generator-ы. Не статические поддерживает, а на статические лови syntax error. Наверное это баг(static * name()); - Для удобного доступа к родительским методам (имею ввиду наследование классов) придуман super. Но… Если вы переопределяете конструктор класса, вы:
- Обязаны вызвать super, чтобы получить доступ к this.
- Да да. До этого момента this отсутствует как таковой. Соответственно вызвать родительский конструктор, предварительно задав какие-нибудь поля новому объекту, без бунов не получится. Зачем они так сделали? о_О.
- Методы и генераторы заданные в теле класса будут не-enumerable. Но для получения их списка можно воспользоваться: Object.getOwnPropertyNames(Object.getPrototypeOf(this)).
Пока что это все грабли на которые я наткнулся. В скором времени ожидается поддержка со стороны Firefox.