Can arguments shift place?

In the passport-local library I’m rebuilding their example project. new LocalStrategy() receives a verify callback in argument 1.

  new LocalStrategy(function(username, password, cb) {
    db.users.findByUserName(username, function(error, user) {
      if (error) return cb(error);
      if (!user) return cb(null, false);
      if (user.password != password) {
        return cb(null, false);
      return cb(null, user);

However their documentation shows that a configuration object can be passed in argument 1, and then the verify callback moves to argument 2. I don’t think I’ve ever seen that before and it’s making me question what I thought was the stability of parameter inputs and the importance of their order:


passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'passwd',
    passReqToCallback: true,
    session: false
  function(req, username, password, done) {
    // request object is now first argument
    // ...

Am I looking at this wrong, or can arguments indeed shift places depending on the type of element received and/or total number of arguments? (PS: I knew optional arguments could go towards the rear but this early position shifting is totally new to me.)

function Strategy(options, verify) {
  if (typeof options == 'function') {
    verify = options;
    options = {};
  if (!verify) { throw new TypeError('LocalStrategy requires a verify callback'); }
  this._usernameField = options.usernameField || 'username';
  this._passwordField = options.passwordField || 'password';; = 'local';
  this._verify = verify;
  this._passReqToCallback = options.passReqToCallback;

So it checks if the first argument is a function: if it is, then it sets up the config object. It isn’t doing anything too clever here, the order matters, it’s just programatically building the things you need if you use one or the other API.

1 Like