Как удалить неопределенные возвраты в функции Once () (без изменения предыдущей функции) - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть два фрагмента кода, они отличаются по определению функции add (y). Один использует console.log () (оригинальная версия), а другой модифицируется для использования return. Второй способ, которым я могу получить мое приглашение, это ...

Напишите функцию один раз, которая принимает обратный вызов в качестве ввода и возвращает функцию. Когда возвращаемая функция вызывается в первый раз, она должна вызвать обратный вызов и вернуть этот вывод. Если он вызывается в любое дополнительное время, вместо повторного вызова обратного вызова он просто вернет выходное значение с момента первого вызова.

Как я могу выполнить рефакторинг первого кода без изменения add (y) для достижения желаемого результата, который возвращается во втором коде?

//Challenge 4
function addByX(x) {
  function add(y) {
    console.log(y + x);
  }
  return add;
}

var addByTwo = addByX(2);

// now call addByTwo with an input of 1
//addByTwo(1);
// now call addByTwo with an input of 2
//addByTwo(5);

//Challenge 5
function once(func) {
  var answer;

  function inner(x) {
    if (!answer) {
      answer = func(x);
      return answer;
    } else {
      return answer;
    }
  }
  return inner;
}

var onceFunc = once(addByTwo);

// UNCOMMENT THESE TO TEST YOUR WORK!
console.log(onceFunc(5)); //should log 7
console.log(onceFunc(10)); //should log 7
console.log(onceFunc(9001)); //should log 7

ВТОРОЙ КОД (работает)

//Challenge 4
function addByX(x) {
  function add(y) {
    return y + x;
  }
  return add;
}

var addByTwo = addByX(2);

// now call addByTwo with an input of 1
//addByTwo(1);
// now call addByTwo with an input of 2
//addByTwo(5);

//Challenge 5
function once(func) {
  var answer;

  function inner(x) {
    if (!answer) {
      answer = func(x);
      return answer;
    } else {
      return answer;
    }
  }
  return inner;
}

var onceFunc = once(addByTwo);

// UNCOMMENT THESE TO TEST YOUR WORK!
console.log(onceFunc(5)); //should log 7
console.log(onceFunc(10)); //should log 7
console.log(onceFunc(9001)); //should log 7

Ответы [ 2 ]

0 голосов
/ 28 апреля 2018

Чтобы расширить то, что @Barmar написал в своем комментарии, в первом примере ваша внутренняя функция add ничего не возвращает, поэтому ее возвращаемое значение будет неопределенным. Следовательно, ответ остается ложным при каждом вызове «inner», и поэтому захваченная функция «addByTwo» вызывается все три раза. Вот почему вы получаете чередующийся номер, который представляет собой результат сложения, зарегистрированный в самом «add», и неопределенный, который является зарегистрированным возвращаемым значением. Вы исправляете это во втором примере, возвращая возвращаемое значение из 'add'.

Теперь я хотел бы отметить пару вещей, которые могут быть вам полезны.

1) Ваш второй пример все равно будет неудачным, если вы передадите -2 в первый раз, когда вы вызываете 'OnceFunc'. Зачем? Потому что это утверждение:

if (!answer) {

Проверяет, является ли ответ ложным, что равно 0 (-2 + 2). Вы можете решить эту проблему, проверив, не является ли ответ неопределенным.

2) Я не знаю, насколько вам нужно, чтобы это было гибким, но при использовании метода apply в вашей захваченной функции вам не нужно указывать аргументы для inner. Это означает, что передаваемая вами функция может принимать ноль, один или несколько аргументов.

Вот пример взлома вашего кода, когда передается -2 (как указано в пункте # 1):

function addByX(x) {
  function add(y) {
    return y + x;
  }
  return add;
}

var addByTwo = addByX(2);

function once(func) {
  var answer;

  function inner(x) {
    if (!answer) {
      answer = func(x);
      return answer;
    } else {
      return answer;
    }
  }
  return inner;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(-2)); //should log 0
console.log(onceFunc(10)); //should log 0, but it won't

И здесь исправлено решение проблемы, упомянутой в # 1, и обеспечение гибкости, упомянутой в # 2:

function addByX(x) {
  function add(y) {
    return y + x;
  }
  return add;
}

function mult(a, b) {
  return a * b;
}

var addByTwo = addByX(2);

function once(func) {
  var answer;

  function inner() {
    if(typeof answer === 'undefined') {
      answer = func.apply(null, arguments);
      return answer;
    } else {
      return answer;
    }
  }
  return inner;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(-2)); // should log 0
console.log(onceFunc(10)); // should log 0, this time it will
console.log(onceFunc(9001)); // should log 0, and again it will


// this can also be re-used with a function that accepts multiple parameters (or none)
var onceFuncMult = once(mult);

console.log(onceFuncMult(3, 5)); // 15
console.log(onceFuncMult(8, 5)); // still 15

Надеюсь, что это полезно и предоставляет немного дополнительной информации, чтобы помочь вам в этом.

0 голосов
/ 28 апреля 2018

Мы можем использовать замыкания для захвата, когда функция была вызвана один раз. Когда флаг для called равен true, он уже был вызван, в этом случае он возвращает value, который был установлен при первом запуске функции. В качестве альтернативы, если функция запускается впервые, мы устанавливаем callback TO true и value на функцию cb, вызываемую с параметром str. Мы возвращаем это значение в любом случае.

function string_callback(cb) {
  let called = false,
    value;
  return function(str) {
    if (called) return value;
    called = true;
    value = cb(str);
    return value;
  }
}

let my_func = string_callback((input) => input.toUpperCase());
my_func("hihihih");

console.log(my_func("banana"));
console.log(my_func("banana"));
console.log(my_func("banana"));
Write a function once that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback
again it will simply return the output value from the first time it was called.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...