将参数引入另一个函数

时间:2017-04-15 12:39:46

标签: javascript

一个参数 - 另一个函数 - 并返回一个" memoized"该功能的版本。 A"记忆"函数的版本缓存并返回其调用的结果,以便当使用相同的输入再次调用它时,它不会运行其计算,而是从缓存返回结果。请注意,以前的结果应该可以按任何顺序检索而无需重新计算。

foo = function (x) {
console.log("calculating!");
return x + 5;
}

var memoizedFoo = memoize(foo);

memoizedFoo(5);
// calculating!
// 10

memoizedFoo(5);
// 10 (notice how 'calculating!' is not printed this time)

memoizedFoo(10);
// calculating!
// 15

1 个答案:

答案 0 :(得分:2)

我认为问题是如何写memoize。您可以将给定参数的第一个结果存储在容器中,如果可以,则返回将使用该容器的函数。

这是一个ES5示例,仅适用于可以有用地转换为字符串的参数值,如字符串,数字,布尔值:



function memoize(f) {
  // Storage for this function's results
  var values = Object.create(null);
  return function(arg) {
    // Already have it?
    if (Object.hasOwnProperty.call(values, arg)) {
      // Yes, return it
      return values[arg];
    }
    // No, get it, remember it, and return it
    return values[arg] = f(arg);
  };
}

var foo = function (x) {
  console.log("calculating!");
  return x + 5;
};

var memoizedFoo = memoize(foo);

console.log(memoizedFoo(5));
// calculating!
// 10

console.log(memoizedFoo(5));
// 10

console.log(memoizedFoo(10));
// calculating!
// 15




如果您需要支持其他类型的参数,则需要使用其他结构或Map polyfill。这带给我们......

...在ES2015 +中,我们可以使用Map,这使得它可以使用更广泛的参数值:



function memoize(f) {
  // Storage for this function's results
  const values = new Map();
  return function(arg) {
    // Already have it?
    if (values.has(arg)) {
      // Yes, return it
      return values.get(arg);
    }
    // No, get it, remember it, and return it
    const value = f(arg);
    values.set(arg, value);
    return value;
  };
}

const foo = function (x) {
  console.log("calculating!");
  return x.foo + 5;
};

const memoizedFoo = memoize(foo);

const firstArg = {foo:5};
console.log(memoizedFoo(firstArg));
// calculating!
// 10

console.log(memoizedFoo(firstArg));
// 10

const secondArg = {foo:10};
console.log(memoizedFoo(secondArg));
// calculating!
// 15

// Note that maps consider equivalent but distinct objects as different (of course),
// so we don't get the memoized reslt from
// `firstArg` here
const thirdArg = {foo:5};
console.log(memoizedFoo(secondArg));
// calculating!
// 10