6

I have a function that takes multiple optional arguments. Currently the function isn't assigning default values in the manner I expect.

var test1 = function(arg1, arg2, arg3, arg4) {

    arg1 = arg1 || "arg1";
    arg2 = arg2 || "arg2";

    var obj = {
      arg1: arg1,
      arg2: arg2,
      arg3: arg3,
      arg4: arg4
    };

    return(obj);

};

var obj1 = test1(arg3 = "notarg1", arg4 = "notarg2"); // Why are these values assigned to arg1 & arg2 instead of 3 & 4?

console.log(obj1);

I don't understand this. Javascript seems to ignore my (arg3 = "notarg1", arg4 = "notarg2") assignments and instead behaves as though (arg1 = "notarg1", arg2 = "notarg2", arg3 = undefined, arg4 = undefined) was my input.

  var test2 = function(arg1, arg2, arg3, arg4) {

    if (arg1 === null) {
      arg1 = "arg1";
    }
    if (arg2 === null || arg2 === "undefined") {
      arg2 = "arg2";
    }

    var obj = {
      arg1: arg1,
      arg2: arg2,
      arg3: arg3,
      arg4: arg4
    };

    return(obj);

  };

  var obj2 = test2(arg3 = "notarg1", arg4 = "notarg2")

  console.log(obj2);

I'm not sure if this is worth including. The situation doesn't change.

3
  • There's a good article on default parameters at MDN. Note that it's an ECMAScript 2015 feature though.
    – RobG
    Commented Nov 14, 2015 at 12:36
  • you are sending two parameters to the function therefore the value are assigned to first two properties of the returning object
    – Azad
    Commented Nov 14, 2015 at 12:46
  • 1
    Those are not default parameters. You're just putting assignments as the arguments to that call. JavaScript does not have named arguments!
    – Bergi
    Commented Nov 14, 2015 at 12:53

2 Answers 2

18

JavaScript doesn't have a feature for naming the argument you're specifying when calling a function, so this line:

var obj1 = test1(arg3 = "notarg1", arg4 = "notarg2");

...doesn't do what you think it does. It does this:

arg3 = "notarg1";
arg4 = "notarg2";
var obj1 = test1("notarg1", "notarg2");

E.g., the arg3 = "notarg1" in the function call is just an assignment to a variable (in this case, probably an implicit global), and the way the assignment operator works is that it assigns the value and the result of the operation is the value that was assigned.

To get the default for args 1 and 2, using your code, you'd have to specify undefined:

var obj1 = test1(undefined, undefined, arg3, arg4);

There, you are specifying args 1 and 2, but the value you're giving them is falsey, and so your function's arg1 = arg1 || "arg1" will take "arg1" (and similarly for arg2).

If you have more than about three arguments, you might look at using options objects instead:

function test1(options) {
    var arg1 = options.arg1 || "arg1";
    var arg2 = options.arg2 || "arg2";
    var arg3 = options.arg3 || "arg3";
    var arg4 = options.arg4 || "arg4";

    console.log(arg1, arg2, arg3, arg4)
}

test({arg3: "notarg1", arg4: "notarg2"});

Output:

arg1, arg2, notarg1, notarg2

Just for completeness, ES2015 (aka ES6) adds default argument values, but you still can't call the function the way you showed in your question. The ES2015 syntax does simplify the code in your function, though.

// ES2015+
function test1(arg1 = "arg1", arg2 = "arg2", arg3, arg4) {
    // ....
}

Again, though, what you do when calling it is the same, there's still no special "matching up the names" feature as there is in some languages.

2
  • 1
    So there's no way to allow the arguments to be left out? Commented Nov 14, 2015 at 12:34
  • @GeeBrownit: Not in that way, no, but you can pass an options object instead. I just added a bit about that. Commented Nov 14, 2015 at 12:35
3

A better way would be to pass an object into the function instead. That way you don't have to worry about missing arguments.

var test1 = function(options) {

    var arg1 = options.arg1 || "arg1";
    var arg2 = options.arg2 || "arg2";
    ...
};

var obj1 = test1({ arg1: "notarg3", arg2: "notarg1" });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.