在JavaScript中传递匿名函数中的参数

时间:2013-08-12 20:06:40

标签: javascript

有时我会看到用参数编写的JavaScript,前提是已经有一个设置值或者是一个带方法的对象。以这个jQuery示例为例:

$(".selector").children().each(function(i) {
    console.log(i);
});

在记录i时,在查看jQuery i方法中的选择器子项时,您将获得该迭代中each的值。

以Node.js为例:

http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
}).listen(8888);

您可以在此处看到requestresponse正在传递,并且它们包含可以对其执行操作的方法。

对我来说,这似乎是将一个函数传递给createServer函数,其中两个参数已经附加了方法。

我的问题是多部分:

  1. 这些论点来自哪里?
  2. 如果这些只是一个非函数函数,它们如何接收可以像其他函数一样执行的参数?
  3. 如何创建可以采用我自己的参数的函数?
  4. 这是否使用闭包的力量?

5 个答案:

答案 0 :(得分:15)

  

对我来说,这看起来像是将一个函数传递给createServer函数,其中两个参数已经附加了方法。

没有。他们将一个函数传递给createServer,它带有两个参数。稍后将使用调用者输入的任何参数调用这些函数。例如:

function caller(otherFunction) {
     otherFunction(2);
 }
caller(function(x) {
    console.log(x); 
});

将打印2。

更高级,如果不是你想要什么,你可以使用属于所有函数的bind方法,这将创建一个已绑定指定参数的新函数。 e.g:

caller(function(x) {
    console.log(x);
}.bind(null, 3);
});

现在将打印3,并且传递给匿名函数的参数2将成为未使用且未命名的参数。

无论如何,这是一个密集的例子;请查看bind的链接文档,了解绑定的效果如何。

答案 1 :(得分:3)

让我们看一下$.each示例:

each: function (obj, callback, args) {
    var value,
    i = 0,
        length = obj.length,
        isArray = isArraylike(obj);

    if (args) {
        if (isArray) {
            for (; i < length; i++) {
                value = callback.apply(obj[i], args);

                if (value === false) {
                    break;
                }
            }
        } else {
            for (i in obj) {
                value = callback.apply(obj[i], args);

                if (value === false) {
                    break;
                }
            }
        }

        // A special, fast, case for the most common use of each
    } else {
        if (isArray) {
            for (; i < length; i++) {
                value = callback.call(obj[i], i, obj[i]);

                if (value === false) {
                    break;
                }
            }
        } else {
            for (i in obj) {
                value = callback.call(obj[i], i, obj[i]);

                if (value === false) {
                    break;
                }
            }
        }
    }

    return obj;
}

调用
$(".selector").children().each(function(i) {
    console.log(i);
});

像:

return $.each.call(this, callback /* this is your function */, args /* which is an additional thing people rarely use*/ )

这是您想要查看的行(在第一个块中)

callback.call(obj[i], i, obj[i]);

它正在调用回调,并将对象作为上下文传递 - 这就是为什么你可以在循环中使用this的原因。然后迭代i然后与上下文相同的对象都作为参数发送到回调。这有点像魔术;直到你看到源代码。

答案 2 :(得分:1)

这是一个将参数传递给匿名函数的示例

    var a = 'hello';

    // Crockford
    (function(a){alert(a)}(a));

    // Others
    (function(a){alert(a)})(a);

它使用闭包,因为它是一个匿名函数(它实际上取决于你如何写它)

答案 3 :(得分:0)

是的,您将函数作为参数传递。您传递的函数当然会有自己的参数。

而且,这些参数可以是任何包括可能有自己方法的对象等等。

http.createServer将接受一个函数,它将知道函数的参数如何。一种方法是检查传入函数的arguments属性。或者api开发人员可能已经使用了实际的元素。

这个函数的作者将知道期望什么作为参数,并将在api documentation中记录它。

答案 4 :(得分:0)

如果查看createServer的代码,它看起来像这样:

function createServer (handleRequestAndResponseFunction) {
    handleRequestAndResponseFunction(actualRequest, actualReponse);
}
好吧,不,不会,但这是一个简单的例子。 createServer接受一个接受两个参数的function

用更现实的术语来说,当你传入两个参数的函数时,它会做任何中间件处理和它需要的东西,然后调用该函数,传递它自己的请求和响应变量。