barbarian meets coding

WebDev, UX & a Pinch of Fantasy

Mastering the Arcane Art of JavaScript-mancy for C Sharp Developers - Chapter 3: Useful Function Patterns - Default Arguments

| Comments

The Mastering the Arcane Art of JavaScript-mancy series are my humble attempt at bringing my love for JavaScript to all other C# developers that haven’t yet discovered how awesome this language and its whole ecosystem are. These articles are excerpts of the super duper awesome JavaScript-Mancy book a compendium of all things JavaScript for C# developers.

In the next few articles of the javascript-mancy series I will detail several patterns you can use in JavaScript to achieve default arguments, multiple arguments and function overloading.

We’ll start with how to use default arguments and values in JavaScript both with the current version on JavaScript (ES5) and the upcoming ECMAScript 2015 that brings native support for defaults.

JavaScript-Mancy

Using default arguments in JavaScript

A Pattern For Using Default Arguments in JavaScript Today

If you are new to javascript, you may have noticed the following statement and wondered what (the heck) it meant:

1
2
3
4
5
6
7
// from jquery loads.js (https://github.com/jquery/jquery/blob/master/src/ajax/load.js)
type: type || "GET",

// or from yeoman yo router.js (https://github.com/yeoman/yo/blob/master/lib/router.js)
this.conf = conf || new Configstore(pkg.name, {
    generatorRunCount: {}
  });

These two examples have been taken from jQuery and yo if you’d like to take a closer look

Well, that’s how you declare defaults in JavaScript. Since there is no native support for default arguments (as of ES5), you make use of the || (OR) operator that returns the first truthy expression of those being evaluated or the last expression if none is truthy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// using any web dev tools in your browser
> false || 42 || false
// => 42

> "" || false
// => false

> "" || {}
// => Object {}

> var numberOfPotatos = undefined
> numberOfPotatos || 3
// => 3

> numberOfPotatos = 5
> numberOfPotatos || 3
// => 5

Here you have a complete example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function castIceCone(mana, otherConsiderations){
    // we take advantage of the || operator to define defaults
    var mana = mana || 5,
        otherConsiderations = otherConsiderations || {},
        direction = otherConsiderations.direction || 'in front of you',
        caster = this || 'God almighty';

    console.log(format("${caster} spends ${mana} mana and casts a terrible ice cone ${direction}"));

    // an utility function to mimic ES6 templating xD
    function format(str){
        return str.split(' ')
        .map(function(token){
            if (/\$\{.*\}/.test(token))
                return eval(token.match(/\$\{(.*)\}/)[1]);
            return token;
        }).join(' ');
    };
}

castIceCone();
// => God almighty spends 5 mana and casts a terrible ice cone in front of you

var jaime = {
    toString: function(){return 'Jaime the Mighty';},
    castIceCone: castIceCone
};
jaime.castIceCone(10, { direction: 'towards Mordor'})
// => Jaime the Mighty spends 10 mana and casts a terrible ice cone towards Mordor

You can test run this example yourself at jsFiddle.

Native Default Arguments with ECMASCript 2015

ECMAScript 2015, the latest version of JavaScript, makes it very easy to declare default arguments:

You can find these examples in this jsFiddle, in order to run them and experiment with ES2015 I recommend you to head over to https://babeljs.io/repl/ which has a very nice REPL that provides support for running ES2015 code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    // run on babel.js
    function castIceCone(mana=5){
        // we take advantage of the || operator to define defaults
        var caster = this || 'God almighty';

        // note this new ES2015 template strings btw
        console.log(`${caster} spends ${mana} mana and casts a terrible ice cone`);
    }

    castIceCone();
    // => God almighty spends 5 mana and casts a terrible ice cone

    var jaime = {
        toString: function(){return 'Jaime the Mighty';},
        castIceCone: castIceCone
    };
    jaime.castIceCone(10, { direction: 'towards Mordor'})
    // => Jaime the Mighty spends 10 mana and casts a terrible ice cone

Defaults in JavaScript are not limited to “constant” expressions like in C# optional arguments. In JavaScript you can use even objects and the new destructuring syntax to assign object properties to variables directly.

In the example below we use the object {direction: 'in front of you'} as a default value for the second argument and automatically declare a variable direction and assign the 'in front of you' value to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    // run on Babel
    // defaults are not limited to constant values, you can even use objects
    function castIceCone(mana=5, {direction='in front of you'}={}){
        var caster = this || 'God almighty';

        // new template strings
        console.log(`${caster} spends ${mana} mana and casts a terrible ice cone ${direction}`);
    }

    castIceCone();
    // => God almighty spends 5 mana and casts a terrible ice cone in front of you

    var jaime = {
        toString: function(){return 'Jaime the Mighty';},
        castIceConePro: castIceConePro
    };
    jaime.castIceConePro(10, { direction: 'towards Mordor'})
    // => Jaime the Mighty spends 10 mana and casts a terrible ice cone towards Mordor

And you are not limited to arbitrary objects either, you can use any expression, for instance, a function expression:

1
2
3
4
5
6
7
8
9
// defaults are not limited to constant values
function castSpell(spell=function(){console.log('holy shit a callback!');}){
    spell();
}

 castSpell();
 // => holy shit a callback!
 castSpell(function(){console.log("balefire!!!! You've been wiped out of existence");});
 // => balefire!!!! You've been wiped out of existence

Concluding

In this article you learned how to use defaults in JavaScript up to ES5 and beyond with the new native support for defaults that is coming with ES2015. Up next, more function patterns with multiple arguments and the rest operator.

Interested in Learning More JavaScript? Buy the Book!

Are you a C# Developer interested in learning JavaScript? Then take a look at the JavaScript-mancy book, a complete compendium of JavaScript for C# developers.

a JavaScriptmancy sample cover

References

More Articles in These Series

Comments