How to put default arguments (default) in a JavaScript function?

30

In R this would be very simple:

funcao <- function(x=10) return(x)

If you call funcao() without arguments, the result will be 10 .

How to do the same in JavaScript? And how do I know if there are default values in the function without having to read the code?

    
asked by anonymous 09.05.2014 / 17:28

6 answers

36

The other answers are correct in general usage, but if you want to be super strict and correct, you need to take the variable arguments into consideration. See this:

// Função identidade, com argumento padrão 10.
function f(x) {
    x = x || 10;
    // if (x == null) x = 10;
    // x = typeof x !== 'undefined' ? x : 10;
    return x;
}

f()           // => Retorna 10
f(3)          // => Retorna 3
f(null)       // => Retorna 10. Epa! Era para isso retornar null não?
f(undefined)  // => Retorna 10. Também!
f(0)          // => 10? Tá de brincadeira né?

Every function when invoked receives a special variable called arguments . It works as an array (it has the property length and can be accessed numerically [0] , [1] , ...). For this identity function the most correct would be to do the following:

// Agora processando o arguments.
function f() {
    x = arguments.length > 0 ? arguments[0] : 10;
    return x;
}

f()     // => Retorna 10
f(3)    // => Retorna 3
f(null) // => Retorna null. Isso!

You can even add an error if more arguments are used:

if (arguments.length > 1) throw new Error("Too many arguments! Expected 1.");
    
09.05.2014 / 18:41
16

In javascript that current browsers (2015) use would have to have a if somehow within the function. But in the future, with browsers that support the new ES6 standard is already possible.

What is possible today (2015):

Nowadays, with the version of JavaScript that browsers use this is not possible. The solution to use is to check the value inside the function, as you mentioned in the question.

For example:

function b(a){
   if (typeof a == 'undefined') a = 1;
   return a;
}

Note: Firefox is already implementing some of ES6's ideas but this is not cross-browser compatible nowadays, hence not in production.

With ES6 - "Default function parameters"

When the new version of JavaScript is implemented in browsers, as Firefox is already doing in this case, the solution will be (according to the specifications of ECMAscript ) as it is in PHP (and that Firefox is already applying).

function b (a = 1) {
   return a;
}
console.log(b()); // dá: 1
    
09.05.2014 / 17:35
14

Just as a curiosity (since the default is still that of version 5).

The ECMAScript 6 (Codename Harmony) includes a proposal of syntax for parameters with default values. You may already experience the new syntax in Firefox . According to Wikipedia the expected release date for the new default is December 2014 :

function multiply(a, b = 1) {
  return a*b;
}

multiply(5); // 5

UPDATE : Updating the response in November 2018. # , also known as ES2015 was released in June 2015 with syntax support above for default function parameters . This new syntax is supported in modern versions of major browsers, with the notable exception of Internet Explorer ( see compatibility table in MDN ).

    
09.05.2014 / 18:28
11

There is no way to do this in a practical way.

However, this answer does not please me, and knowing that javascript is such a dynamic language, I decided to use some of my time to reflect, research and finally, putting together a method to allow easy indication of default values.

How to use:

var funcao = (function(x) { return x; }).WithDefaults([10]);

Or, a slightly more complex example, which is supported by WithDefaults :

var myFunc = (function (a) {
    return a + arguments[1];
}).WithDefaults([, "y"]);

Method code Function.prototype.WithDefaults

(function () {
    var setDefaults = function (a, d) {
        var l = Math.max(a.length, d.length);
        var p = [];
        for (var i = 0; i < l; i++)
            p[i] = i >= a.length || typeof a[i] == 'undefined' ? d[i] : a[i];
        return p;
    }

    var copyProperties = function (to, from, defs) {
        to.innerFunction = from;
        to.toString = function () {
            var strDefs = "";
            for (var i = 0; i < defs.length; i++)
                strDefs += (i > 0 ? ", " : "")
                    + (typeof defs[i] != 'undefined' ? JSON.stringify(defs[i]) : "");

            return "(" + from.toString() + ").WithDefaults(["
                + strDefs + "])";
        };
        for (var key in from)
            to[key] = from[key];
        return to;
    }

    var fnCreators = {
        0: function (f, d, sd, cp) {
            return cp(function () {
                return f.apply(this, sd(arguments, d));
            }, f, d);
        },
        1: function (f, d, sd, cp) {
            return cp(function (p1) {
                return f.apply(this, sd(arguments, d));
            }, f, d);
        },
        2: function (f, d, sd, cp) {
            return cp(function (p1, p2) {
                return f.apply(this, sd(arguments, d));
            }, f, d);
        },
        3: function (f, d, sd, cp) {
            return cp(function (p1, p2, p3) {
                return f.apply(this, sd(arguments, d));
            }, f, d);
        }
    };

    function getFnCreator(numParams) {
        if (typeof fnCreators[numParams] != 'undefined')
            return fnCreators[numParams];

        var paramNames = [];
        for (var i = 0; i < numParams; i++) {
            paramNames[i] = "p" + (i + 1);
        }

        fnCreators[numParams] = new Function("f", "d", "sd", "cp",
            "return cp(function(" + paramNames.join(",") + ") {\
                return f.apply(this, sd(arguments, d));\
            }, f, d);");

        return fnCreators[numParams];
    }

    Function.prototype.WithDefaults = function (defs) {
        var creator = getFnCreator(this.length);
        return creator(this, defs, setDefaults, copyProperties);
    }
})();

Example of using the WithDefaults method in jsfiddle

    
09.05.2014 / 21:14
9

There are a few ways, but I prefer it as follows:

function func(x){
    x = typeof x !== 'undefined' ? x : 10;
    return x;
}

Example

    
09.05.2014 / 17:34
7

This way:

function Retorno(x){
    if(x == 0)
        return x;

    x = x || 10; // Valor de x caso existir ou 10 que é o padrão
    return x;
}

I recommend reading that answer from Miguel Angelo that explains better how the || (or) as coalescence operator in Javascript.

    
09.05.2014 / 17:33