在Javascript中返回具有预先指定的常量的函数

时间:2017-09-14 23:46:07

标签: javascript

我想创建一个返回函数的函数。

const f = (value) => {
  return (input) => (value <= input);
};

预期:

f(3).toString();
// "(input) => (3 <= input);"

eval(f(3).toString())(4);
// true

实际:

f(3).toString();
// "(input) => (value <= input);"

eval(f(3).toString())(4);
// Error: input is undefined

我可以使用预先指定的动态常量生成函数吗?

我正在制作一种代码生成器。我尝试将函数转换为字符串并保存为'some.js'。我的目标是'some.js'的用户在使用它时不必知道f的参数。

3 个答案:

答案 0 :(得分:0)

预先分配常数的过程&#34;被称为partial application

您可以使用函数原型方法bind自行完成此操作,例如:

const add = (x, y) => x + y
const add3 = add.bind(null, 3)
add3(4) // === 7

您还可以使用有用的第三方库,例如lodash's partialpartialRight方法。

上述示例不起作用的原因是因为f(3)返回了一个函数。调用toString将为您提供该函数体的字符串表示。

当您调用f(3)的结果时,它将eval字符串,但带有一个闭包,其中value已定义且值为3。由于您在字符串上调用eval,因此它正在全局范围内查找名为value的命名变量。

如果你不知道我指的是什么,我建议你阅读javascript closures,这里有很多资源。

我希望这是朝着正确方向迈出的一步,如果有些事情不明确,请写下评论:)

答案 1 :(得分:0)

而不是f(3).toString(),您可以存储f.toString() + '(3)'

f = value => input => value <= input

s = `(${f})(${3})`
console.log(s)
console.log(eval(s))

console.log(f(3)(4))
console.log(eval(s)(4))

答案 2 :(得分:-1)

除了使用eval之外,你几乎就在那里。

SELECT store, products_qty, count(*) FROM (
   SELECT store, count(p.id) as products_qty, count(i.id) as invoices_count 
   FROM invoices i
   LEFT JOIN products p ON (p.invoice_id = i.id)
   GROUP BY price, i.id
) AS temp GROUP BY store, products_qty;