All streams
Search
Write a publication
Pull to refresh
52
0
Егор @termi

User

Send message
Нужно было «облегчить» тело стрелочной функции. В первоначальном варианте просто запрещалось использование arguments внутри стрелочной функции. Позже ограничение смягчили и теперь arguments закрепляется вместе с this и super.

Стоит заметить, что в es6, в принципе, рекомендуется не использовать arguments — в классических функциях его поддержка оставлена только для обратной совместимости.
Стрелочные функции решают определённый пласт задач, в приведённом вами месте стрелочным функциям не место. То есть, это всё равно что написать: «не стоит бездумно заменять все классические функции на стрелочные» и быть безусловно правым.
Да, вы правы. Я поторопился и не проверил
Запятая в начале строки — это довольно известный code style, которым я пользуюсь в своих личных проектах.
Картинки в начале и конце — не более чем шутка.
Код функции `idGen` предваряется зачеркнутым саркастическим словосочетанием, что, по замыслу, должно было настроить на шутливый тон.
Вот только сейчас подумал, что приведённый вами пример можно записать очень лаконично на es6:
 foo.bar.baz.bind(...[])

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

> занятная штука, но это немного другое
Объясните пожалуйста, чем вас не устраивает данное предложение? Я от него просто в восторге.
Выше я написал, что 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 и arguments места вызова
Я не совсем понял вопрос.

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

Я ответил на ваш вопрос?
Согласен с вами, но разработчики стандарта сошлись на том, что в этом плане работа должна быть аналогична функции у которой был закреплён контекст с помощью .bind
* короткий синтаксис — посмотрите на последний скриншот в посте — от такого короткого синтаксиса слёзы наворачиваются

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

Оптимизация проводится за счет следующих особенностей:
1. Arrow function нельзя использовать в качестве конструктора
2. Переменные this, arguments и super берутся от родительского function scope
3. Внутри arrow function нельзя использовать «собственный» объект arguments — а это означает, что не надо синхронизировать значения аргументов и псевдо-массива arguments
4. Функции call, apply и bind не могу сменить контекст
К стати, вам наверняка будет интересна вот эта ветка дискуссии Merging Bind Syntax with Relationships в которой как раз обсуждают нужный вам оператор. К сожалению, этот вопрос был поднят слишком поздно и в es6 этот оператор, скорее всего, не попадёт.
Вот пример:
// Using a function as an extension method:
function f() { return this.x; }

obj.x = "abc";
obj::f(); // "abc";
> www.slideshare.net/BrendanEich/value-objects2
сильно сомневаюсь, что такое когда-нибудь попадёт в стандарт ecmascript.

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

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

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

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

Но, в целом, я с вами полностью согласен — описанную вами проблему стрелочные функции не решают.
В частном же случае, лично я никогда не испытывал проблем с методами класса. А обработчики DOM-событий, прекрасно пишутся используя handleEvent и не теряют контекст.
Ждем, когда все это дело появится в хроме и сафари

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

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

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

Так что, не всё так плохо. Я, наоборот переживаю, что в es6 вошло так мало новых возможностей.
Еще, у вас в тесте ( явный .call ) ошибка. Вы, я уверен непреднамеренно, изменили тест «scope», чтобы он явно проигрывал. Вот я сделал правильную версию теста: jsperf.com/bind/5
Там в папке tests всё есть. Вот например из первого теста стрелочных функций:
es6:
{
    let test = 987;
    var result = (function() {
        var this$0 = this;

        var obj = {
            test: 123
            , arr: () => () => this.test + test
        };

        function innerTest() {
            console.log(this$0.test === "testString");
        }
        innerTest();

        return obj.arr()();
    }).call({test: "testString"});
}

es5:
{
    var test$0 = 987;
    var result = (function() {var this$1 = this;
        var this$0 = this;

        var obj = {
            test: 123
            , arr: function()  {return function()  {return this$1.test + test$0}}
        };

        function innerTest() {
            console.log(this$0.test === "testString");
        }
        innerTest();

        return obj.arr()();
    }).call({test: "testString"});
}
У стрелочных функций очень много неявных моментов, я специально писал тесты, чтобы покрыть все возможные кейсы: 1, 2, 3, 4. Боюсь написать макрос, который будет проходить эти тесты довольно сложно.
Зачем пользоваться неполноценной реализацией (да ещё и медленной) если можно воспользоваться транслятором и получить не только стрелочные функции, но и деструктуризацию, классы, дефолтные значения и много другое?

Information

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