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

Passing arguments in anonymous functions in JavaScript

有时我会看到用一个参数编写的javascript,前提是它已经有一个设定值或者是一个带有方法的对象。以jquery为例:

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

当登录i时,当查看jquery each方法中的选择器子级时,您将得到该迭代中的i的值。

以node.js为例:

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

您可以在这里看到,requestresponse正在被传递,它们包含自己的方法,可以对其进行操作。

在我看来,这就像是在向createServer函数传递一个函数,其中有两个参数已经附加了方法。

我的问题是多部分的:

  • 这些论点是从哪里来的?
  • 如果这些只是一个非函数,它们如何接收可以像其他函数一样操作的参数?
  • 如何创建可以接受我自己的参数的函数??
  • 这是否使用了闭包的力量??

  • To me, this looks like were passing a function to the createServer function with two arguments that have methods already attached to them.

    不,他们正在向createServer传递一个函数,它接受两个参数。这些函数稍后将使用调用者输入的任何参数来调用。例如。:

    1
    2
    3
    4
    5
    6
    function caller(otherFunction) {
         otherFunction(2);
     }
    caller(function(x) {
        console.log(x);
    });

    将打印2。

    更高级的是,如果这不是您想要的,您可以使用属于所有函数的bind方法,这将创建一个新函数,其中指定的参数已经绑定。例如。:

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

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

    无论如何,这是一个密集的例子;请检查bind的链接文档以了解绑定如何更好地工作。


    我们来看看$.each的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    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;
    }

    这个电话是从

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

    像:

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

    这是你想看的那一行(在第一个街区)

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

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


    下面是将参数传递到匿名函数的示例

    1
    2
    3
    4
    5
    6
    7
        var a = 'hello';

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

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

    它使用闭包,因为它是一个匿名函数(实际上,这完全取决于您如何编写它)。


    如果您查看了CreateServer的代码,它会如下所示:

    1
    2
    3
    function createServer (handleRequestAndResponseFunction) {
        handleRequestAndResponseFunction(actualRequest, actualReponse);
    }

    好吧,不,不会,但这只是一个简单的例子。CreateServer接受接受两个参数的function

    更现实的说法是,当您传入由两个参数组成的函数时,它会做任何中间件处理和它需要做的事情,然后调用该函数,传递它自己的请求和响应变量。


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

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

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

    此函数的编写者将知道期望的参数,并将其记录在api documentation中。