How does this work? Optional first argument used in Express (err, req, res, next) or (req, res, next)
Asked Answered
A

3

12

With Express / Connect I can set up an middleware function in either of the formats:

function(req, res, next) // first argument will be a request

Or

function(err, req, res, next) // first argument will be an error

Stepping back from Express, Connect, to basic JavaScript: I don't understand is how this is possible to have an optional first argument?

How can express know that my function will accept an err object first? I thought to make this possible the structure would have to be like the following:

function(req, res, next, err)

Am I missing something basic here? Is it possible to query how many arguments a function is expecting?

The middleware function is passed to express, so the arguments variable is not valid. although length is correct... I think I have figured it out, would be good to have confirmation to whether this is the case. Example below:

var fn;

fn = function (one, two) {};
console.log(fn.length); // 2

fn = function (one, two, three) {};
console.log(fn.length); // 3
Acclimate answered 8/12, 2011 at 12:45 Comment(1)
I was always wondering if it would be possible or not, then convinced myself that its not!Longlongan
S
9

I think I have figured it out, would be good to have confirmation to whether this is the case

var fn;

fn = function (one, two) {};
console.log(fn.length); // 2

fn = function (one, two, three) {};
console.log(fn.length); // 3

Yes, that's correct. The length property of a Function instance is the number of formal parameters (declared arguments) it has. This is hidden away in Section 13.2 of the spec, steps 14 and 15.

So it's quite easy for the code calling the function to check fn.length and pass it the optional first argument, or not, depending on that. This does mean, of course, that it's entirely possible to write a function that would handle the four-argument version, but fools the framework by using arguments rather than formal parameters. So you wouldn't do that. :-)

(Apologies for misreading your question the first time.)

Specimen answered 8/12, 2011 at 13:12 Comment(2)
p.s. do you know the name of this technique?Acclimate
@Ross: Sorry, I missed that comment. I don't know that it has a specific name. You're tested the arity of the function.Specimen
C
2

The first function has 3 arguments, the second one has 4 arguments, so Express/Connect looks at the number of arguments.

It's not possible to switch between arguments.

Chiliarch answered 8/12, 2011 at 12:50 Comment(0)
T
1

Express spends quite a long time looking at the arity of the function; i.e. how many arguments that are in there:

function foo(err, req, res, next) {
    if (arguments.length === 3) { // err isn't there
        next = res;
        res = req;
        req = err;
    }
    ...
}

So. Detect how many arguments there are, and shuffle variables accordingly. I've even seen some Node.js-modules that does the automatically for you.

And while I haven't checked up recently, there were some cases where messing with the arguments-builtin would disable all optimizations in V8.

Teacake answered 8/12, 2011 at 12:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.