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

在JavaScript中的匿名函数中传递参数,javascript,Javascript,有时我会看到JavaScript是用一个参数编写的,该参数已经有一个设置值,或者是一个带有方法的对象。以jQuery为例: $(".selector").children().each(function(i) { console.log(i); }); 当记录i时,当查看jQuery每个方法中的选择器子项时,您将获得该迭代中的任何i的值 以Node.js为例: http.createServer(function(request, response) { response.wr

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

$(".selector").children().each(function(i) {
    console.log(i);
});
当记录
i
时,当查看jQuery
每个
方法中的选择器子项时,您将获得该迭代中的任何
i
的值

以Node.js为例:

http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
}).listen(8888);
您可以在这里看到,
request
response
正在被传递,它们包含了自己可以执行的方法

对我来说,这看起来像是在向
createServer
函数传递一个函数,该函数包含两个参数,这些参数已经附加了方法

我的问题是多部分的:

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

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

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

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

    此函数的编写者将知道什么是预期的参数,并将其记录在
    api文档中

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

    没有。他们正在向
    createServer
    传递一个函数,该函数包含两个参数。这些函数稍后将使用调用者放入的任何参数进行调用。e、 g:

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

    更高级的是,如果这不是您想要的,您可以使用“属于所有函数”的方法,该方法将创建一个已绑定指定参数的新函数。e、 g:

    caller(function(x) {
        console.log(x);
    }.bind(null, 3);
    });
    
    现在将打印3,传递给匿名函数的参数2将成为未使用且未命名的参数


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

    让我们看看
    $。每个
    都有一个示例:

    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;
    }
    
    比如:

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

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

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

    如果您查看createServer的代码,它将如下所示:

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


    更现实的说法是,当您传入包含两个参数的函数时,它会执行它需要的任何中间件处理和内容,然后调用该函数,传递它自己的请求和响应变量。

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

        var a = 'hello';
    
        // Crockford
        (function(a){alert(a)}(a));
    
        // Others
        (function(a){alert(a)})(a);
    

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

    @SethenMaleno
    request
    response
    只是
    createServer
    方法的参数。当该方法实际被调用时,它将被传递两个对象,表示您可以操作的请求和响应。声明参数只是设置函数的期望值;当函数为called@SethenMaleno您没有将它们作为参数传递。您将它们声明为参数。您的代码显示“调用
    http.createServer
    并传递此函数。当服务器准备就绪时,调用我刚才提供的函数并传递两个参数。”在您的函数中,您将这两个参数引用为
    request
    response
    @SethenMaleno,就像普通函数参数一样,参数名称只是别名。您只是说“在这个函数中,我希望传递给它的第一个参数被引用为
    请求
    …而传递给它的第二个参数被引用为
    响应
    ”。当node实际调用您的函数时,它会传递两个(非常)复杂的对象(参数),它们具有属性/方法(例如
    .write()
    )。@Ian我创建了一个JSFIDLE,以了解我认为(小规模)代码正在做什么,请看:@SethenMaleno Yes!完全正确。首先我应该这么做来帮助解释
    function createServer (handleRequestAndResponseFunction) {
        handleRequestAndResponseFunction(actualRequest, actualReponse);
    }
    
        var a = 'hello';
    
        // Crockford
        (function(a){alert(a)}(a));
    
        // Others
        (function(a){alert(a)})(a);