Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I would like a JavaScript function to have optional arguments which I set a default on, which gets used if the value isn't defined. In Ruby you can do it like this:

def read_file(file, delete_after = false)
  # code
end

Does this work in JavaScript?

function read_file(file, delete_after = false) {
  // Code
}
share|improve this question

11 Answers 11

up vote 2385 down vote accepted

From ES6/ES2015, default parameters is in the language specification.

function read_file(file, delete_after = false) {
  // Code
}

just works.

Reference: Default Parameters - MDN

Default function parameters allow formal parameters to be initialized with default values if no value or undefined is passed.

Pre ES2015,

There are a lot of ways, but this is my preferred method - it lets you pass in anything you want, including false or null. (typeof null == "object")

function foo(a, b)
{
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}
share|improve this answer
148  
You can also encapsulate it as such: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; } and then you can call it as a = defaultFor(a, 42); – Camilo Martin Sep 2 '12 at 5:56
4  
@SiPlus and you got extra reference errors for free of charge while trying to use undefined objects :p Even while it may work with some browsers and might be faster, null is still an object and undefined is reference to primitive type that is trying to tell that there is nothing here, not even null. See here, both cases in nutshell: JavaScript/Reference/Global_Objects/undefined. – Sampo Sarrala Nov 3 '12 at 1:29
6  
if you check against the property of an object, then typeof is redundant. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; } This won't throw reference errors and is concise. – Dziamid May 17 '13 at 11:06
2  
This didn't work for me. If you pass in no value you can't use typeof on the parameter. You have to instead use var === undefined – Rick Eyre Jul 19 '13 at 15:14
5  
I know it's really minor, but I don't like how you are assigning a = a and b = b when those parameters are not undefined. Also, that ternary operator with a bit complicated condition may be hard to read for future maintainers. I would prefer following syntax: if (typeof a == 'undefined') a = 42 - no unnecessary assignment plus a little bit easier to read. – Daddy32 Dec 9 '14 at 15:31
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

This assigns to delete_after the value of delete_after if it is not a falsey value otherwise it assigns the string "my default here". For more detail, check out Doug Crockford's survey of the language and check out the section on Operators.

This approach does not work if you want to pass in a falsey value i.e. false, null, undefined, 0 or "". If you require falsey values to be passed in you would need to use the method in Tom Ritter's answer.

When dealing with a number of parameters to a function, it is often useful to allow the consumer to pass the parameter arguments in an object and then merge these values with an object that contains the default values for the function

function read_file(values) {
    values = merge({ 
        delete_after : "my default here"
    }, values || {});

    // rest of code
}

// simple implementation based on $.extend() from jQuery
function merge() {
    var obj, name, copy,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length;

    for (; i < length; i++) {
        if ((obj = arguments[i]) != null) {
            for (name in obj) {
                copy = obj[name];

                if (target === copy) {
                    continue;
                }
                else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    return target;
};

to use

// will use the default delete_after value
read_file({ file: "my file" }); 

// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" }); 
share|improve this answer
86  
I find this insufficient, because I may want to pass in false. – Tom Ritter May 21 '09 at 20:11
43  
I find it's adequate for most situations – Russ Cam May 21 '09 at 20:16
32  
This also doesn't work for 0. :( – Alex Kahn Jun 13 '12 at 15:07
35  
It doesn't work for any falsey value – Russ Cam Jun 18 '12 at 6:20
34  
Because it doesn't work for falsey values, it may create a maintenance nightmare. A bit of code that has always been passed truthy values before and suddenly fails because a falsey one is passed in should probably be avoided where a more robust approach is available. – jinglesthula Oct 31 '12 at 20:34

I find something simple like this to be much more concise and readable personally.

function pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 
share|improve this answer
5  
Update: If you're using underscore.js already I find it even better to use _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. Using the global namespace as shown in this answer is by many considered a bad practice. You may also consider rolling your own utility for this common task (eg. util.default(arg, "defaul value")) if don't want to use underscore, but I mostly end up using underscore sooner or later anyway no point in reinventing the wheel. – andersand Aug 15 '14 at 20:12
    
@andersand I like the idea of something like util.default(arg, "defaul value")) would you or @tj111 mind posting a quick demo? – JasonDavis Oct 13 '14 at 2:08
1  
I actually recommend this one, i use it and call it "por" which stands for "parameter or" – Murplyx Apr 21 '15 at 16:59
    
Don't say typeof arg == 'undefined', instead say arg === undefined – OsamaBinLogin Oct 20 '15 at 15:06
    
@OsamaBinLogin what you say is correct for current JS - the older test persists because on some browsers it used to be possible to overwrite undefined with some other value, causing the test to fail. – Alnitak Nov 16 '15 at 11:34

In ECMAScript 6 you will actually be able to write exactly what you have:

function read_file(file, delete_after = false) {
  // Code
}

This will set delete_after to false if it s not present or undefined. You can use ES6 features like this one today with transpilers such as Babel.

See the MDN article for more information.

share|improve this answer
1  
ECMAScript 6 I suppose... (I would have corrected by myself but I can't make edits < 6 chars) – Zac Jun 1 '15 at 20:15
    
Waiting for browser any get ECMAScript 6 – Adriano Resende Jul 8 '15 at 13:05
    
What would Babel transpile this to? – harryg Jul 9 '15 at 11:31
1  
@harryg: babeljs.io/repl/… – Felix Kling Jul 9 '15 at 13:22
2  
Here is the compatibility table for ES6 kangax.github.io/compat-table/es6/#default_function_paramete‌​rs Unfortunately this syntax isn't supported yet. – freemanoid Jul 9 '15 at 19:03

that solution is work for me in js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
share|improve this answer
3  
What happens if delete_after is 0 or null? It will not work correct for these cases. – Dmitri Pavlutin Dec 20 '15 at 9:33
    
Actually, it will work in this case. – Stephan Bijzitter Sep 5 at 12:37

As an update...with ECMAScript 6 you can FINALLY set default values in function parameter declarations like so:

function f (x, y = 7, z = 42) {
  return x + y + z
}

f(1) === 50

As referenced by - http://es6-features.org/#DefaultParameterValues

share|improve this answer
6  
This answer is not useful because it is a duplicate – user Nov 6 '15 at 0:48

Just use an explicit comparison with undefined.

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}
share|improve this answer

being a long time C++ developer (Rookie to web development :)), when I first came across this situation, I did the parameter assignment in the function definition, like it is mentioned in the question, as follows.

function myfunc(a,b=10)

But beware that it doesn't work consistently across browsers. For me it worked on chrome on my desktop, but did not work on chrome on android. Safer option, as many have mentioned above is -

    function myfunc(a,b)
    {
    if (typeof(b)==='undefined') b = 10;
......
    }

Intention for this answer is not to repeat the same solutions, what others have already mentioned, but to inform that parameter assignment in the function definition may work on some browsers, but don't rely on it.

share|improve this answer
    
Assignment within the function definition also doesn't work in IE 11, which is the most current version of IE for Windows 8.1. – DiMono Jul 19 at 2:52
    
In case anyone's wondering, function myfunc(a,b=10) is ES6 syntax, there are links to compatibility tables in other answers. – gcampbell Sep 18 at 9:00

Default Parameter Values

With ES6, you can do perhaps one of the most common idioms in JavaScript relates to setting a default value for a function parameter. The way we’ve done this for years should look quite familiar:

function foo(x,y) {
 x = x || 11;
 y = y || 31;
 console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17

This pattern is most used, but is dangerous when we pass values like

foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42

Why? Because the 0 is falsy, and so the x || 11 results in 11, not the directly passed in 0. To fix this gotcha, some people will instead write the check more verbosely like this:

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

we can now examine a nice helpful syntax added as of ES6 to streamline the assignment of default values to missing arguments:

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11 in a function declaration is more like x !== undefined ? x : 11 than the much more common idiom x || 11

Default Value Expressions

Function default values can be more than just simple values like 31; they can be any valid expression, even a function call:

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

As you can see, the default value expressions are lazily evaluated, meaning they’re only run if and when they’re needed — that is, when a parameter’s argument is omitted or is undefined.

A default value expression can even be an inline function expression call — commonly referred to as an Immediately Invoked Function Expression (IIFE):

function foo( x =
 (function(v){ return v + 11; })( 31 )
) {
 console.log( x );
}
foo(); // 42
share|improve this answer

To anyone interested in having there code work in Microsoft Edge, do not use defaults in function parameters.

function read_file(file, delete_after = false) {
    #code
}

In that example Edge will throw an error "Expecting ')'"

To get around this use

function read_file(file, delete_after) {
  if(delete_after == undefined)
  {
    delete_after = false;
  }
  #code
}

As of Aug 08 2016 this is still an issue

share|improve this answer

Yes, This will work in Javascript. You can also do that:

function func(a=10,b=20)
{
    alert (a+' and '+b);
}

func(); // Result: 10 and 20

func(12); // Result: 12 and 20

func(22,25); // Result: 22 and 25
share|improve this answer

protected by Samuel Liew Oct 5 '15 at 9:18

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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