主要问题是 Javascript 是一种函数式语言,因此您可以将函数作为参数传递给其他函数。例如,在其他语言中,您可能经历过向函数传递指针或句柄。考虑一个简单的情况,其中有一些数学函数:
function add(a,b) {return (a+b)};
function subtract(a,b) {return (a-b)}:
现在我可以创建一个新函数:
function longWayAroundTheBarn(num1,num2,theFunc)
{
// invoke the passed function with the passed parameters
return theFunc(num1,num2);
}
并这样称呼它:
console.log(longWayAroundTheBarn(1,2,add));
> 3
或者甚至像这样:
console.log(longWayAroundTheBarn(longWayAroundTheBarn(2,2,subtract),4,add);
> 4
显然,这将是一个愚蠢的使用回调,但您通常可以想象,以这种方式“插入”函数的能力可能非常强大。
考虑一下是否无法传递函数。这可能是您实现此目的的一种方式:
function reallyLongWayAround(num1,num2,funcName)
{
if(funcName==='add')
return add(num1 ,num2);
else if (funcName === 'subtract')
return subtract(num1, num2);
}
您可以想象,除了必须编写和维护的代码非常繁琐之外,它并没有那么强大,因为reallyLongWayAround
函数只能调用它知道的代码。通过传递函数,我的longWayAroundTheBarn
不在乎我是否创建新函数并将其传递给它。请注意,由于弱类型,它甚至不需要关心它传递的参数。也许你想实现类似的东西
function businessDaysBetween(d1,d2)
{
// implementation left as a reader exercise
};
调用以下方法就可以了:
longWayAroundTheBarn(new Date(2014,1,15), new Date(2014,1,22),businessDaysBetween)
回到你提到的具体案例,req
and res
正如一个答案所示,它们不是“局部变量”——它们被称为参数或参数。你没有向他们传递任何东西。它们由调用函数传递给您。你实际上可以打电话给他们fred
and barney
如果你愿意的话,尽管这将是一个糟糕的主意。要点是它们将被调用并填充请求和响应对象。
实际上,您甚至不必在函数签名中包含参数,您只需进行如下回调,并通过读取参数数组来使用传递给函数的第二个参数(注意,它实际上不是一个数组,而是在许多方面表现相似)。这将是一个非常非常糟糕的想法,但我再次试图说明这一点。
var http = require('http');
http.createServer(function () {
arguments[1].writeHead(200, {'Content-Type': 'text/plain'});
arguments[1].end('Hello World\n');
}).listen(1337, 'myhost');