• Как функции декораторы работают изнутри?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    а вы вот так перепишите, возможно понятнее будет

    // Вот так работает
    const decoratedDouble = decorator(double);
    console.log(decoratedDouble(5)); // 10
    // decoratedDouble это уже другая функция. та, что возвращается из декоратора.
    // Просто вы ее перезаписываете в уже существующую переменную.
    
    // А вот так нет
    console.log(decorator(double(5))); // [Function (anonymous)]


    ну и второй вариант правильнее писать так, т.е. и прямой вызов работает:

    console.log(
      decorator(double)(5) // декоратор возвращает функцию, которую надо вызвать
    ); // 10
    Ответ написан
    Комментировать
  • Как функции декораторы работают изнутри?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Что делает декоратор — получает одну и создаёт новую функцию.

    Пример из жизни. Декоратор == мастерская жуликов. Был обычный банкомат (функция). Засунули его в мастерскую злодеев и получили новый банкомат. Новый банкомат выглядит как прежний, но внутри теперь ещё и отправляет данные карты и введённые пин-коды злодеям. При этом свои внешние обычные действия он продолжает выполнять: принимает карту, показывает баланс.

    1. Каким образом аргумент функции double() передаётся в аргумент функции, которую возвращает декоратор?

    Наоборот: теперь работают с новой функцией, которую вернул декоратор. А уже она, внутри, вызывает double() в которую и передаёт аргумент, с которым её вызвали.

    2. Почему не работает прямой вызов функции-декоратора? decorator(double(5))
    в таком варианте аргументом в decorator() попадает что? — не сама функция double, а результат её выполнения с аргументом 5.

    Наверное, вам пока непривычно, что аргументом функций может быть не только, скажем, число,
    а и целая функция. Почувствуйте разницу:
    (fn2( fn1 ))(arg)
    // fn2 получает аргументом функцию fn1
    // возвращает новую функцию, и уже та выполняется
    // с аргументом arg
    
    fn2( fn1( arg ))
    // fn1 выполняется с аргументом arg
    // результат попадает аргументом в fn2
    // возвращается результат вызова fn2
    Ответ написан
    3 комментария
  • Как функции декораторы работают изнутри?

    SilenceOfWinter
    @SilenceOfWinter
    та еще зажигалка...
    function double(num) {
        return num * 2;
    }
    function decorator(innerFn) {
        return function (num) {
            if(isNaN(num)) {
                throw new TypeError('Ошибка! Не число.');
            }
            return innerFn(num);
        };
    }
    
    const decoratedDouble = decorator(double);
    alert(decoratedDouble(5));


    decorator просто оборачивает переданную функцию в другую(`function (x)`) и возвращает её.
    decorator(double(5))
    не работает потому что ты напрямую вызываешь double, в результате в decorator передается 10(5*2), а не double.

    В js есть класс Proxy позволяющий упростить подобные действия.
    Ответ написан
    2 комментария
  • Как функции декораторы работают изнутри?

    @wonderingpeanut
    Декораторы это функции высшего порядка, то есть функции, которые принимают в качестве аргумента функцию или возвращают новую функцию.
    Они используются для того, чтобы генерализировать часть какого-то функционала. В твоем случае - проверка входящих данных на соответствие какому-то типу.

    1. Каким образом аргумент функции double передаётся в аргумент функции, которую возвращает декоратор?

    Функция декоратор возвращает новую функцию, которая принимает какие-то параметры. То есть при вызове декоратора ты получаешь новую функцию, в которую можешь передать аргумент.

    const decoratedDouble = decorator(double);
    // decoratedDouble это функция, которая принимает аргумент х, проверяет его на соответствие типу 'number'
    // и выполняет на нем инструкции, описанные функцией double
    // тело функции выглядело бы так:
    function decoratedDouble(x) {
      if (isNaN(x)) {
        throw new TypeError(...);
      }
    
      return x * 2
    }


    2. Почему не работает прямой вызов функции-декоратора?

    Декоратор ожидает аргумент типа function, а ты передаешь в него результат выполнения функции double - число.
    decorator(double) // Function
    decorator(double)(5) // 10
    decorator(double)('Hello World') // TypeError
    Ответ написан
    Комментировать