Pull to refresh

Comments 62

Ждем, когда все это дело появится в хроме и сафари, тогда можно и первые опыты ставить ну и конечно nodejs там то точно можно будет не заботиться о совместимости. Фитча действительно удобная.
Однако когда читаешь новые счецификации по ES хочется спросить у ребят, где они закупаются:
особенно когда читаешь о перезагрузке операторов, переопределении typeof, всяких int32, int64, int32x4, int32x8
Ждем, когда все это дело появится в хроме и сафари

Уже сейчас можно использовать через трансляцию es6 -> es5

особенно когда читаешь о перезагрузке операторов, переопределении typeof, всяких int32, int64, int32x4, int32x8

Вышеперечисленного не будет, «int32, int64, int32x4, int32x8» предполагается только для определения StructType.

Так что, не всё так плохо. Я, наоборот переживаю, что в es6 вошло так мало новых возможностей.
Так трансляция это не интересно, её можно было бы использовать и 10 лет назад, а можно написать свой транслятор, который будет делать все что угодно. Об этом никто не спорит. но интересна же нативная поддержка.

Лично мне кажется новые фишки должны вводиться очень аккуратно, щас все идет в сторону усложенения, и читаемость кода падает как по мне. Вот смотрю я на эту презентацию www.slideshare.net/BrendanEich/value-objects2 и думаю, появиться все это и как жить?
> www.slideshare.net/BrendanEich/value-objects2
сильно сомневаюсь, что такое когда-нибудь попадёт в стандарт ecmascript.

А что касается трансляции, тут важно понимать, что несмотря на наличие CoffeeScript, LifeScript и подобных, это всё-таки были не стандарты. А ecmascript 6 — это стандарт. Однако, вопрос об отличии стандарта от свободных поделок это тема отдельной дискуссии. Я надеюсь, что вы меня поняли.

Кроме того, используя трансляцию сейчас, вы в будущем сможете просто отключить её для браузеров которые поддерживают es6.
Глядя на синтаксис хочется плакать.
Не нашел каких-то особых плюсов использования стрелочных функций перед обычными.
НУ почему же? очень подходит для колбэков когда там 1 строчка кода не городить столько лишних символов
Обычно в колбэках важен контекст.
Arrow functions обладают следующими преимуществами:
* сохранение контекста
* короткий синтаксис
* оптимизированное выполнение js-движками
* сохранение super (на данный момент не так актуально)

По моему, вполне достойно.
* сохранение контекста — согласен, это плюс
* короткий синтаксис — посмотрите на последний скриншот в посте — от такого короткого синтаксиса слёзы наворачиваются
* оптимизированное выполнение js-движками — кроме оптимизации this не увидел в статье никаких других оптимизаций

Мне кажется, достаточно было добавить к текущему синтаксису сахар в виде удобного сохранения контекста и не городить новый синтаксис
* короткий синтаксис — посмотрите на последний скриншот в посте — от такого короткого синтаксиса слёзы наворачиваются

Ну это же я специально навернул, для привлечения внимания. За такой код обычно по рукам бьют в приличном обществе.
* оптимизированное выполнение js-движками — кроме оптимизации this не увидел в статье никаких других оптимизаций

Оптимизация проводится за счет следующих особенностей:
1. Arrow function нельзя использовать в качестве конструктора
2. Переменные this, arguments и super берутся от родительского function scope
3. Внутри arrow function нельзя использовать «собственный» объект arguments — а это означает, что не надо синхронизировать значения аргументов и псевдо-массива arguments
4. Функции call, apply и bind не могу сменить контекст
Ладно, я не собирался никого переубеждать. Это моё личное мнение.
Вот пункт 4 смущает немного: call, apply и bind не могут сменить контекст молча или покажут какую-то ошибку?
Согласен с вами, но разработчики стандарта сошлись на том, что в этом плане работа должна быть аналогична функции у которой был закреплён контекст с помощью .bind
короткий синтаксис — посмотрите на последний скриншот в посте — от такого короткого синтаксиса слёзы наворачиваются


В статье вообще какое-то форматирование кода странное — то запятая в начале строки, то => переносится на другую строку. Интересно, это внутри компании такой styleguide.
Запятая в начале строки — это довольно известный code style, которым я пользуюсь в своих личных проектах.
Картинки в начале и конце — не более чем шутка.
Код функции `idGen` предваряется зачеркнутым саркастическим словосочетанием, что, по замыслу, должно было настроить на шутливый тон.
Это верно, если забить на обратную совместимость. К примеру для callback-функци jQuery обычное дело использовать в качестве this — элемент, который вызвал событие.
и обычное дело как раз таки мешать такому поведению, ибо когда вы работаете в ооп видеть при ивенте в колбеке сам элемент — ужасно. Вы навешиваете событие и внутри хотите работать с инстансом своего класса, а уж элемент лучше получать из ивента.

Не одним JQ едины и там далеко не лучшая реализация такого поведения она не применима для больших проектов, а простые слайдеры писать надо далеко не всем. Тот же backbone успешно передает правильный контекст в коллбеки к события и жизни становится простой и удобной
А я не говорил, что это хорошая практика. Я говорю о том, что обратная совместимость является приоритетной при разработке новых стандартов JS.
А где же тут обратная совместимость?
Он довольно медленный
А есть ссылка на какой-нибудь тест, посмотреть на сколько?
Для меня только улучшение читабельности при рутинных операциях с масивами и передача «правильного» this без bind уже дотаточно.
Нормальный такой синтаксис, как во всех приличных домах.
Преимущества — лаконичность и захват this, больше никаких.

Кстати, они развернули грабли другой стороной — как теперь получить this и arguments места вызова? Писать old-style анонимную функцию и без вариантов?
> получить this и arguments места вызова
Я не совсем понял вопрос.

this будет такой, каким он был в момент создания arrow function.
А переменное число параметров реализуется через rest

Я ответил на ваш вопрос?
rest — да, это я проглядел.
а this… я даже не знаю, когда вообще может понадобиться this контекста вызова, а не контекста создания функции, но сам факт невозможности его получить меня печалит.
Невозможность получить this лишь мешает нам нафигачит методы вот в таком стиле (а то многие бы покусились) а также помогает разработчиком интерпретатора оптимизировать скорость таких функций. Я вижу только плюсы.
а в JQuery-хэндлерах лазить на каждую мелочь в Event.currentTarget? Мне как-то не по нраву.
Я вам еще раз повторю, в вашем плагинчике для слйдера — все ок, ничего более не надо. Если у вас ООП код большого приложения то предполагается что при клике по кнопочке вы будите юзать не $(this).fadeIn(), а работать с конкретным инстансом класса и вызывать его методы и тут вам надо чтобы this был не текущий объетк дома, а конктекст вашего приложения.
Всё это замечательно, вкусно, жду их много лет, но от проблемы биндинга это избавляет лишь частично, когда нужно передать анонимную функцию с сохранением контекста.
Методы объекта нельзя привязывать к нему же, в его нотации. Методы прототипа «класса» придется привязывать так же, в конструкторе, как это делается в CoffeeScript.
В итоге, в большинстве случаев мы имеем всё то же — foo.bar.baz.bind(foo.bar).
Проблему бы решил оператор привязки контекста, например в LiveScript это foo.bar~baz.
Либо метод биндинга в прототипе Object, аналогичный функции bindKey из LoDash.
И не говорите, что добавление свойства в прототип Object — зло, их там и так уже расплодилось…
Скрытый текст
Object.prototype.constructor
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()
Object.prototype.toLocaleString()
Object.prototype.toString()
Object.prototype.valueOf()
Object.prototype.__proto__
Object.prototype.__count__
Object.prototype.__noSuchMethod__
Object.prototype.__parent__
Object.prototype.__defineGetter__()
Object.prototype.__defineSetter__()
Object.prototype.__lookupGetter__()
Object.prototype.__lookupSetter__()
Object.prototype.eval()
Object.prototype.toSource()
Object.prototype.unwatch()
Object.prototype.watch()

В самом примитивном виде это выглядит так:
Object.defineProperty(Object.prototype, 'tie', {
  value: function(key){
    var that = this
      , fn   = that[key];
    return function(){
      return fn.apply(that, arguments);
    }
  }
});

В итоге, вместо foo.bar.baz.bind(foo.bar) мы получим foo.bar.tie('baz').
Или, например,
var log = console.tie('log'); // вместо console.log.bind(console);
log(42); // -> 42

Правда, до свидания IE 8-.
Как активный пользователь Google Closure Compiler в Anvanced mode, я не могу спокойно смотреть на код в котором смешаны скобочная (['name']) и точечная(.name) нотации. После GCC такой код перестанет работать.

Ещё один довод — это поддержка в IDE, которым очень сложно анализировать код типа `console.tie('log')`.

Но, в целом, я с вами полностью согласен — описанную вами проблему стрелочные функции не решают.
В частном же случае, лично я никогда не испытывал проблем с методами класса. А обработчики DOM-событий, прекрасно пишутся используя handleEvent и не теряют контекст.
К стати, вам наверняка будет интересна вот эта ветка дискуссии Merging Bind Syntax with Relationships в которой как раз обсуждают нужный вам оператор. К сожалению, этот вопрос был поднят слишком поздно и в es6 этот оператор, скорее всего, не попадёт.
Вот пример:
// Using a function as an extension method:
function f() { return this.x; }

obj.x = "abc";
obj::f(); // "abc";
Я тоже не особый любитель смешивать точечную и скобочную нотации, но за неимением лучшего и из-за явного нарушения принципа DRY в foo.bar.baz.bind(foo.bar) не отказался бы от подобного метода в стандартной библиотеке языка. Жму код uglify с максимально агрессивными параметрами, никаких проблем с подобным не возникает, если у GCC проблемы с подобным — сочувствую его пользователям :)

Обсуждения читаю регулярно, в чуть более приятном формате, данное предложение видел, занятная штука, но это немного другое :) Вроде раньше что-то более похожее проскакивало.

Вот еще вариант на базе Proxy, но более тяжелый.
> Жму код uglify с максимально агрессивными параметрами
GCC даже в simple mode намного агресивнее uglify. И пользователи GCC, в основном, знают об этом.

> занятная штука, но это немного другое
Объясните пожалуйста, чем вас не устраивает данное предложение? Я от него просто в восторге.
А объясните плиз, зачем вам вообще сжатие?.. Экономия не так чтобы совсем драматическая (если у вас код не весит конечно мегабайт 5-6), каналы сейчас у всех толстый стали. Экономия на спичках и уменьшение читаемости для тех, кто захочет ваш код посмотреть в отладчике. Или для сокрытия от посторонних глаз и делается? :)
Вот только сейчас подумал, что приведённый вами пример можно записать очень лаконично на es6:
 foo.bar.baz.bind(...[])

Единственный тут недостаток — это пустой массив, но к нему можно привыкнуть.
Уж думал плохо rest / spread из ES6 понимаю, а нет — не работает. Данное выражение привяжет как контекст undefined, без strict mode он будет преобразован в глобальный объект (window).

А по поводу оператора — ничего против не имею, интересная штука, но больно глобальная, появление — маловероятно, обсуждения никакого.
Да, вы правы. Я поторопился и не проверил
А чем данный пример по поведению будет отличаться от
f.call(obj)

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

var MyClass = function(){ this.init.apply( this, arguments ); };
MyClass.prototype =
{
  init: function(){},
  some1: function(){},
  some2: function(){},
}


Если я опишу его как:
var MyClass = function(){ this.init.apply( this, arguments ); };
MyClass.prototype =
{
  init: function(){},
  some1: () => { /* ... */ },
  some1: () => { /* ... */ },
}

то, судя по статье, some1, some2, init будут вызываться с this === window. Получается о5 потребуются какие то обёртки или прочие шаманства?
Выше я написал, что arrow functions не решают эту проблему. Однако, не только вы заметили столь серьёзную недоработку и люди обсуждают возможность ввести оператор :: для решения описанной вами проблемы, смотрите комментарий.

Хотя, в коде который вы приводите, закреплять this не нужно. Скорее вам нужна более лаконичная запись функций (я прав?). Ваш код можно переписать на es6, используя т.н. shorthand:
var MyClass = function(){ this.init.apply( this, arguments ); };
MyClass.prototype =
{
  init: function(){},
  some1() { /* ... */ },
  some1() { /* ... */ },
}

а если ещё использовать и остальные фичи es6, тогда всё совсем хорошо будет:

class MyClass{
  constructor(...rest) {
    this.init(...rest);
  }
  
  init(){ /**/ }
  some1() { /* ... */ }
  some1() { /* ... */ }
}
Не совсем понял ваш комментарий. Я бы хотел избавиться от всевозможных

this.$dom_obj.click( this.someFuncton.bind( this ) );

и прочих применений .bind, только ради того, чтобы внутри someFunction не потерять this. Сейчас используя nodeJS мне приходится вызывать .bind даже у генераторов, если я передаю их в какую-нибудь внешнюю функцию. Это один из самых неприятных моментов для меня в JS (второй это невозможность передать что-нибудь по указателю или ссылке, если это не объект).
К сожалению, стрелочные функции это не панацея и не помогут в приведённом вами случае. Чтобы было лучше понятно, можно относится к стрелочным функциям не как к функциям, а как к блокам — то есть стрелочные функции полезны только в рамках того же контекста, в котором были созданы.

В случае же кода this.$dom_obj.click( this.someFuncton.bind( this ) ); придётся всё также использовать .bind либо, вы можете воспользоваться волшебным handleEvent, о нём вы можете почитать в моей недописанной статье, либо в англоязычных источниках
А можно создать стрелочную функцию внутри конструктора?

class MyClass{
  constructor(...) {
    this.myfunc_pow = (x) => {return x*x};
  }
}


Если я правильно понимаю, таким образом мы привяжем эту функцию к данному объекту вне зависимости откуда она будет вызвана.
может кто-нибудь подсказать название цветовой схемы, которая на картинке?
Monokai, включена по умолчанию в Sublime Text 2.
Про this все понятно и здорово. А можете пояснить, зачем они сохраняют arguments контекста?
Нужно было «облегчить» тело стрелочной функции. В первоначальном варианте просто запрещалось использование arguments внутри стрелочной функции. Позже ограничение смягчили и теперь arguments закрепляется вместе с this и super.

Стоит заметить, что в es6, в принципе, рекомендуется не использовать arguments — в классических функциях его поддержка оставлена только для обратной совместимости.
Употреблять стрелочные функции совместно с jQuery надо будет с превеликой осторожностью, так как jQuery подменяет this-контекст классических функций, однако, по-видимому, будет обламываться насчёт this-контекста стрелочных функций.

То есть смотрю я, например, на некоторые свои скрипты и вижу: вздумай я перейти на употребление стрелочных функций, меня ждало бы ошибочное действие буквально на второй из значимых строк кода.
(В том смысле, что если в этой строке заменить классическую функцию на стрелочную, то тогда на следующей же строке значение this будет несколько неожиданным.)
Стрелочные функции решают определённый пласт задач, в приведённом вами месте стрелочным функциям не место. То есть, это всё равно что написать: «не стоит бездумно заменять все классические функции на стрелочные» и быть безусловно правым.
На мой взгляд, это не самая лучшая особенность jQuery, имхо. Всегда использую .each с двумя аргументами, т.к. для меня сохранить this текущего — класс-объекта куда важнее, чем сэкономить 30 символов. Приходится писать нечто вроде:

$list.each( $.proxy( function( ind, item )
{
  ...
}, this ) );

практичеки всегда
Когда стрелочные функции без перекомпиляции можно будет пользовать для написания скриптов, которые будут исполняться в более чем 1 браузере, потребность в jquery в её нынешнем виде врятли будет.
В этом светлом будущем jquery разве что будет абстрагировать от каких-нить вендорных приблуд IE25 \ ФФ100500 \ Хроме 6666666
UFO just landed and posted this here
Да забей, момент был написан для сбора плюса)
jQuery — сахар, стрелочные функции — сахар. кто-то должен уйти.
<зануда>
var result = values.sort((a, b) => a - b);

Даже если массив полон значений, разность которых будет давать -1, 0 или 1, данный код всё равно вызывает некоторые опасения.
</зануда>
В TypeScript почти такие же arrow functions. Только arguments доступен внутри все-таки. Остальное точь-в-точь.
Sign up to leave a comment.