最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Passing arguments in anonymous functions in JavaScript - Stack Overflow

programmeradmin1浏览0评论

Sometimes I see JavaScript that is written with an argument provided that already has a set value or is an object with methods. Take this jQuery example for instance:

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

When logging i, you would get the value of whatever i is in that iteration when looking at the selectors children in the jQuery each method.

Take this Node.js example:

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

You can see here that request and response are being passed and they contain their own methods that can be acted on.

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

My question is a multipart one:

  1. Where do these arguments come from?
  2. If these are just anon functions, how do they receive arguments that can be acted on like other functions?
  3. How do I create functions that can take my own arguments like this??
  4. Does this use the power of closures??

Sometimes I see JavaScript that is written with an argument provided that already has a set value or is an object with methods. Take this jQuery example for instance:

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

When logging i, you would get the value of whatever i is in that iteration when looking at the selectors children in the jQuery each method.

Take this Node.js example:

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

You can see here that request and response are being passed and they contain their own methods that can be acted on.

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

My question is a multipart one:

  1. Where do these arguments come from?
  2. If these are just anon functions, how do they receive arguments that can be acted on like other functions?
  3. How do I create functions that can take my own arguments like this??
  4. Does this use the power of closures??
Share Improve this question asked Aug 12, 2013 at 20:06 SethenSethen 11.3k6 gold badges38 silver badges66 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 19

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

No. They were passing a function to createServer that takes two arguments. Those functions will later be called with whatever argument the caller puts in. e.g.:

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

Will print 2.

More advanced, if this isn't what you want you can use the bind method belong to all functions, which will create a new function with specified arguments already bound. e.g.:

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

Will now print 3, and the argument 2 passed to the anonymous function will become an unused and unnamed argument.

Anyway, that is a dense example; please check the linked documentation for bind to understand how binding works better.

Let's take a look at $.each for the example:

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;
}

This gets called from

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

like:

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

This is the line (in the first block) you want to look at

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

It's calling the callback, and passing the object as the context – this is why you can use this in the loop. Then the iteration i and then the same object as the context are both sent as arguments to the callback. It's a little bit like magic; until you look at the source code.

Here's a example of passing parameters into anonymous function

    var a = 'hello';

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

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

It uses closure, since it's an anonymous function (it actually all depends how you wrote it)

Yes, you are passing functions as arguments. The functions that you pass will of course have their own arguments.

And, these arguments can be anything including objects which may have their own methods, etc.

http.createServer will accept a function and it will know how may arguments that function has. One way to to do this is to check the arguments property of the passed in function. Or the api developer may have used the actual elements.

The writer of this function will know what is expected as arguments and will document it in the api documentation.

If you looked at the code for createServer, it'd look something like this:

function createServer (handleRequestAndResponseFunction) {
    handleRequestAndResponseFunction(actualRequest, actualReponse);
}

ok, no it wouldn't, but it's a simple example. createServer takes a function that accepts two arguments.

In more realistic terms, when you pass in that function of two arguments, it does whatever middleware processing and stuff that it needs to, and then calls that function, passing its own request and response variables.

发布评论

评论列表(0)

  1. 暂无评论