Pull to refresh
54
0
Егор @termi

User

Send message
Хорошая библиотека, но как обычно есть подводные камни.
Во первых,
UPDATE. Забыл сказать, что Sweet.js имеет возможность генерации карт кода (source maps), поэтому сложностей с отладкой (по крайней мере в браузере) быть не должно.

Проблема вся в том, что ни один браузер с поддержкой Source Map не умеет (на данный момент) производить обратное переименовывание переименованных переменных. Т.е. при отладки, если я вижу переменную «x» в коде, то я не смогу посмотреть её значение ни наведя на неё мышку, ни в консоли введя "> x", ни в инспекторе областей видимости — эта переменная будет переименована в что-то типа «x123».

Во вторых, не советую ей пользоваться для трансляции es6 в es5. Лучше воспользоваться «честным» транслятором.
Например, вот подобные правила:
// Array destructuring
case [...front, back] => back.concat(front)

// Object destructuring
case { foo: 'bar', x, 'y' } => x

реализуют очень примитивную поддержку шаблонов деструктуризации. Не находил ещё макросов для Sweet.js которые нормально бы реализовывали трансляцию es6.
ES6 module loader proposal
1.6.3.19 Loader.prototype.translate ( load )
Optionally translate the given source from some other language into ECMAScript.

Делайте свой транслятор и подключайте любой язык. Поверьте, сделать транслятор, например Python->JS легче, чем добавить в браузер полноценную/обновляемую/безопасную поддержку языка
Моя претензия к JS состоит не в конкретной реализации ООП, а в том, что нету единообразия. Кто как хочет, так и рисует свои иерархии...

Классы из ecmascript 6 вы смотрели?
class Animal {
  constructor(name) {
    this.name = name;
  }
 
  say() {
    return this.name + " say:";
  }
}
class Cat extends Animal {
  say() {
    return super.say() + " meow";
  }
}
let tomas = new Cat('Tomas');
console.log(tomas.say());


Ничего не мешает уже сейчас использовать es6 и транслировать его в js. Хотя я конечно понимаю, что у вас есть и другие причины предпочитать Dart, но именно в плане стандартизации ООП в es6 есть какие-никакие подвижки.
Спасибо за статью! Действительно крутой и нужный полифил.
Осталось только несколько вопросов:
1. В Benvie/WeakMap не реализован метод clear — нужно это указать в статье.
2. Конструктор Benvie/WeakMap не работает с Iterator protocol, только с массивами.
3. Не раскрыта тема WeakSet.
В принципе, это работает, но есть нюанс:
1. DOM-объект нельзя назначить в качестве prototype JS-объекту
2. У DOM-объекта нельзя сменить prototype
3. У DOM-объекта нельзя установить некоторые свойства, например toString

Это же касается VB-объектов.

Короче, не юзабельно. Я очень долго экспериментировал.
Вот тут подробное обсуждение: github.com/kriskowal/es5-shim/issues/152
Вот вам идея: не замедлять все браузеры, копируя туда-сюда массивы, а проверять, что текущий браузер — это IE8, а точнее, что браузер не умеет полноценно JavaScript 1.6. Это проверяется достаточно легко:
var supportJS1_6 = false;
try {
    supportJS1_6 = window.isNaN.apply(window, {length: 1, 0: void 0})
}
catch(e) { }

И для IE8 написать отдельную функцию createArrayMethod. Это же позволит вам в будущем выпилить (или вынести) поддержку IE8
В том, что при использовании полифилов, библиотечная функция будет использоваться только в случае отсутствия такой нативной функции. Т.е. в вашем случае, библиотечная реализация bind (которая, к стати в es5-shim сделана лучше, чем в jQuery) будет использоваться только в IE8, а в остальных браузерах будет использоваться нативная функция.
es5-shim полностью реализует Function.prototype.bind и ряд других методов, в том числе фиксит страшный баг в IE8 с Array.prototype.splice
habrahabr.ru/post/199456/#comment_6924098
jQuery.proxy внутри себя не использует нативный bind. Зачем использовать весьма убогий библиотечный метод, если есть нативная альтернатива?
Есть готовые полифилы HTML5-History-API от devote, мой форк, которые делают тоже самое, но только прозрачно для пользователя. У себя в форке я ещё добавил событие pagechange которое срабатывает и на методы pushState/replaceState, и на событие popstate
5. Забыл добавить, что в общем-то, использование History-API не такое удобное как хотелось бы. Т.к. при использовании методов pushState/replaceState не происходит никакого события, то остальная часть приложения ничего не знает о том, что урл сменился. Поэтому в своём форке я добавил событие
pagechange = {
  newUrl: string
  , oldUrl: string
  , popstate: boolean
}

диспатчится оно на window. Срабатывает и на методы pushState/replaceState и на событие popstate
api.jquery.com/jQuery.proxy/ это НЕ bind. Забудте вообще про этот метод в jQuery
Т.е. вы не используете встроенный в движок браузера и весьма оптимизированный Function.prototype.bind только из-за того, что когда-то не во всех браузерах был этот метод?
Просто неочевидный пример. Вот более частый кейс:
var _toString = Function.prototype.call.bind(Object.prototype.toString);

_toString({});     // "[object Object]"
_toString(window); // "[object Window]"
_toString([]);     // "[object Array]"

Т.е. простой вызов функции _toString() используется вместо:
Object.prototype.toString.call( [] )

и
var _toString = Object.prototype.toString
_toString.call( [] )

что весьма удобнее
В статьи не озвучено:
* полифилы: HTML5-History-API от devote, мой форк (используется у нас в компании)
* подводные камни при использовании History-API:
  1. разное срабатывание onpopstate при первой загрузке страницы в Webkit/Blink и FF/Opera
  2. забагованые location.[pathname/href] в старых Chrome/Safari (в том числе на старых Android/iPhone) и Opera 12-: эти браузеры разэкранируют спец символы, при получении значений этих свойств, в отличии от последних версий браузеров
  3. Баги Opera 12- с релативными ссылками при использовании History-API: после второго применения History-API node.href указывает на урл, сформированный из предыдущего установленного через History-API значения и относительной ссылки самого элемента a
  4. Баг в последнем Webkit/Blink с History-API + Fullscreen API: Chromium/Safari выходят из полноэкранного режима (активированного через Fullscreen API) при использовании History-API

В своём форке я исправляю все эти проблемы.

В общем, использование History-API это не панацея и нужно было ещё допиливать API браузера для реального использования в крупном проекте.
> Ничто не мешает в ие создавать новый статический класс и подменять им тот что был.
Мешает ограниченность VBScript'а. Всё-таки VBScript-объекты и JS-объекты совсем разные. Я знаю о чем говорю, потому что много эксперементировал с этим.
> Можно нанэстить прототипов и расширять через них.
Я не понял эту фразу, если честно.
В IE8- host-объекты, VBScript-объекты и объекты JS нельзя смешивать — т.е. нельзя назначить прототипом JS-объекта VBScript-объект и наоборот.
Там конечно есть нюансы, но я очень долго изучал этот вопрос — все пути решения в результате приводят к мелким и неудобным ограничениям, из-за которых просто невозможно универсально использовать какое-либо решение. Например, если создавать экземпляр host-класса, то у него нельзя сменить некоторые встроенные свойства — самое распространённое из которых это «toString», а могут быть недоступны на запись (и на Object.defineProperty) и такие свойства как «length» и т.д.
Для «обычных» объектов в IE8 это реально только через статический VBScript-класс. Ограничение VBScript это то, что статический класс невозможно расширить новыми свойствами. Единственный способ без VBScript — это проверка по таймеру каждые ~10+ мс не изменилось ли значение.
А в данной библиотеки используется экземпляр host-класса XDomainRequest. Над хост-объектами Object.defineProperty в IE8 работает.
В общем, реальных геттеров/сеттеров для любых объектов в IE8 нету и не будет.
Что значит не нужен, что опять по пол страницы для создания XMLHttpRequest писать?

Ну зачем вы так утрируете?
let xhr = new XMLHttpRequest({anon: true});//anonymous request
xhr.open("GET", "api.site.com");
xhr.responseType = "json";
xhr.onload = function(){
    xhr.response;//this is JSON object
}
xhr.send();

Посылает анонимный запрос и получает ответ в JSON формате. Да, я согласен, что этот код без полифилов работать не будет, да и вызов `open` избыточен, но это не пол страницы.

В современных web-приложениях больше необходим socket.io и подобные, чем $.ajax.

Что ещё остаётся?
$.css — менять стили в js-коде это быдлокод, нужно пользоваться css-классами
$.[add/remove/toggle]Class — node.classList.[add/remove/toggle] удобнее и быстрее, да и менять классы в js-коде это моветон — нужно использовать БЭМ модификаторы, методов работы с которыми в jQuery нету.
$.bind и $.trigger — это полный провал и в версии 2.0 они их не улучшили. Можно продолжать использовать только по привычке, и то, с декларативным подходом, вам не понадобится /часто/ использовать $.bind
Выбор ($.find) и манипулирование DOM-элементами ($.append, $.after и т.д.) — эти функции должен предоставлять Декларативный фреймворк, а то, что он «по капотом» использует jQuery не должно вас волновать.

Остаётся только $.Deferred, но его хотят добавить в следующую версию DOM4 API, поэтому он будет поддерживаться браузерами нативно.

Я не говорю, что нужно прекратить использовать jQuery, нет. Просто большинство декларативных фреймворком предоставляют API отличное от jQuery и говорить, что jQuery это неотъемлемая часть языка (тут я утрирую и преувеличиваю, но всё же) это неправильно.
Я может быть сейчас скажу что-то крамольное, но, по моему, jQuery больше не нужен. По крайней мере в новых проектах, где используется декларативный подход, jQuery только мешает. Да, я понимаю, что во многих декларативных фреймворках jQuery используется «по капотом» — ну так пусть он там и остаётся. Раздражает, когда люди продолжают использовать $.proxy, $.each, $.inArray и иже с ними.
[a, _, b] = [1, 2, 3]

Согласен, но всё-таки смысл в том, что синтаксис деструктуризации отличается в CS и ES6. И это печалит.
Часто используете for-of?

В ES6 for-of /будет/ очень полезный. Особенно в сочетании с итераторами и генераторами. Так что я буду всё больше и больше его использовать.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity