Return 不带参数的可变函数
Return variable function without parameters
我正在尝试编写一个 JavaScript 函数来获取一些变量和 returns 一个包含它们的值而不将它们作为参数或引用它们的函数。
一个简单的例子:
function foo(a,b) {
return function(x) {
//doing something with values of a and b, for example:
return a*x + b;
}
}
所以如果我这样做:
var c = foo(2,3);
var d = foo(4,5);
c 和 d 看起来像:
c: function(x) {
return 2*x + 3;
}
d: function(x) {
return 4*x + 5;
}
我希望 foo() 在返回新函数之前用它们的值替换变量 a、b。所以 c 和 d 不需要引用它们之外的一些变量。
我使用 CasperJS 并尝试动态创建由 casper.evaluate()
执行的函数,这些函数将执行的函数沙盒化。这就是为什么它不会按照示例中描述的方式工作的原因。
有什么解决办法吗?
非常感谢!
编辑:
为什么我需要这个?
我尝试用 CasperJS 写一个抽象的爬虫。因此,有一个 "main" 函数可以访问包含多个函数的对象变量 (var site = {...}),casper.evaluate() 将这些函数一个接一个地作为参数。这些函数在打开的网页上执行沙箱,因此它们无法访问网页外的任何变量。他们可以做非常不同的事情,但大多数情况下他们会寻找一种包含 link/image/reference 的标签,替换此引用并 returns 所有这些都在列表中。
此函数可用于链接、图像、css-文件、js-文件等,并且只需要为它们中的每一个使用不同的选择器、属性名称(可能还有 1-2 个其他变量)。
我不能将它们作为这个函数的参数,因为每个函数可能需要不同数量的参数,而 casper.evaluate(site[i]['method']) 调用不知道它们。它调用函数时不带任何参数。
这就是为什么我认为实现一个生成这些函数的函数是最好的方法。但显然这并不像我计划的那样有效。
当然我可以只复制这个函数并替换几个变量。但这会产生大量冗余代码并带来所有缺点。
另一个想法:
使用存储在同一对象中的特定数量的参数调用函数:casper.evaluate(site[i]['method'],site[i]['arg0'],site[我]['arg1']...)
我认为这应该可行,但不是很好,因为每个函数都必须有这个特定数量的参数,即使它不需要一个。而且它只在没有函数需要更多参数的情况下才有效。
function foo(a,b)
{
return new Function("x", "return " + a + "*x+" + b);
}
也许这对您有用。这是您的示例,但允许使用任意数量的参数执行函数。
function foo() {
var func = function() {
//doing something with arguments of the original function:
return arguments;
};
var allArgs = Array.prototype.slice.call(arguments); // 1
allArgs.unshift(null); // 2
return Function.prototype.bind.apply(func, allArgs); // 3
}
- 获取外部函数的所有参数并将它们转换为数组
- 将
null
放在参数列表的开头
- return 已绑定来自外部函数的所有参数的内部函数的副本。我们放在
allArgs
数组开头的 null 用作 bind
函数的 this
参数。
用法示例:
var c = foo(1,2,3,4,5,6);
c(7); // returns: [1, 2, 3, 4, 5, 6, 7]
我正在尝试编写一个 JavaScript 函数来获取一些变量和 returns 一个包含它们的值而不将它们作为参数或引用它们的函数。
一个简单的例子:
function foo(a,b) {
return function(x) {
//doing something with values of a and b, for example:
return a*x + b;
}
}
所以如果我这样做:
var c = foo(2,3);
var d = foo(4,5);
c 和 d 看起来像:
c: function(x) {
return 2*x + 3;
}
d: function(x) {
return 4*x + 5;
}
我希望 foo() 在返回新函数之前用它们的值替换变量 a、b。所以 c 和 d 不需要引用它们之外的一些变量。
我使用 CasperJS 并尝试动态创建由 casper.evaluate()
执行的函数,这些函数将执行的函数沙盒化。这就是为什么它不会按照示例中描述的方式工作的原因。
有什么解决办法吗? 非常感谢!
编辑:
为什么我需要这个? 我尝试用 CasperJS 写一个抽象的爬虫。因此,有一个 "main" 函数可以访问包含多个函数的对象变量 (var site = {...}),casper.evaluate() 将这些函数一个接一个地作为参数。这些函数在打开的网页上执行沙箱,因此它们无法访问网页外的任何变量。他们可以做非常不同的事情,但大多数情况下他们会寻找一种包含 link/image/reference 的标签,替换此引用并 returns 所有这些都在列表中。 此函数可用于链接、图像、css-文件、js-文件等,并且只需要为它们中的每一个使用不同的选择器、属性名称(可能还有 1-2 个其他变量)。 我不能将它们作为这个函数的参数,因为每个函数可能需要不同数量的参数,而 casper.evaluate(site[i]['method']) 调用不知道它们。它调用函数时不带任何参数。 这就是为什么我认为实现一个生成这些函数的函数是最好的方法。但显然这并不像我计划的那样有效。
当然我可以只复制这个函数并替换几个变量。但这会产生大量冗余代码并带来所有缺点。
另一个想法: 使用存储在同一对象中的特定数量的参数调用函数:casper.evaluate(site[i]['method'],site[i]['arg0'],site[我]['arg1']...)
我认为这应该可行,但不是很好,因为每个函数都必须有这个特定数量的参数,即使它不需要一个。而且它只在没有函数需要更多参数的情况下才有效。
function foo(a,b)
{
return new Function("x", "return " + a + "*x+" + b);
}
也许这对您有用。这是您的示例,但允许使用任意数量的参数执行函数。
function foo() {
var func = function() {
//doing something with arguments of the original function:
return arguments;
};
var allArgs = Array.prototype.slice.call(arguments); // 1
allArgs.unshift(null); // 2
return Function.prototype.bind.apply(func, allArgs); // 3
}
- 获取外部函数的所有参数并将它们转换为数组
- 将
null
放在参数列表的开头 - return 已绑定来自外部函数的所有参数的内部函数的副本。我们放在
allArgs
数组开头的 null 用作bind
函数的this
参数。
用法示例:
var c = foo(1,2,3,4,5,6);
c(7); // returns: [1, 2, 3, 4, 5, 6, 7]