JavaScript - Subtleties

JavaScript oftentimes surprises the C/C++ programmer with its subtle gimmicks that make it hard to understand what goes on in the code in the beginning, but further into your carreer - help you develop speed and flexibility in coding even more. Let us take a look at some of those subtleties ourselves.

Multiple export syntaxes exist: see here

You can write in ECMAScript 6 the following:

function foo() {
    var bar = {};
    return bar;
}

export { foo };

However, Node does not accept this syntax. Instead, you need to use another syntax with module.exports as follows:

function foo() {
    var bar = {};
    return bar;
}

var exports = module.exports = {};

Ghost arguments to function calls

Where are arguments sourced from - these, that are listed neither in the main scope, nor in function body?

An example of such a set-up is:

var dir = require('node-dir');

function read_dir(dir_to_scan = '../users') {
    var data = {};
    var options = { shortName: true };

    function finish_callback(err, files){
        if (err) throw err;
        console.log("Users found:\n", data);
    }

    function callback(err, content, filename, next) {
        if (err) throw err;
        data[filename] = content.trim();
        next();
    }

    dir.readFiles(
            dir_to_scan,
            options,
            callback,
            finish_callback);

    return data;
}

The code snippet contains a function which uses another function named callback. Arguments to the callback function are: err, content, filename and next. These arguments, however, do not occur anywhere else in the code. Where do they come from then?

A theory reminder

This theory was sourced from W3Schools[1].

Function parameters are the names listed in the function definition.

Function arguments are the real values passed to (and received by) the function.

Arguments are Passed by Value

The parameters, in a function call, are the function's arguments.

JavaScript arguments are passed by value: The function only gets to know the values, not the argument's locations.

If a function changes an argument's value, it does not change the parameter's original value.

Changes to arguments are not visible (reflected) outside the function.

Objects are Passed by Reference

In JavaScript, object references are values.

Because of this, objects will behave like they are passed by reference:

If a function changes an object property, it changes the original value.

Changes to object properties are visible (reflected) outside the function.

The answer

The argument count to any function is not verified upon call. Therefore, a function can be passed any number - and kind - of parameters, and only upon execution use some of them. Therefore, if the callback function accepts a parameter called err, then the variable err must be passed to the callback() function inside the body of the function dir.readFiles(), where err, as I expect, is defined and then passed further on.

Callbacks

Callback mechanism is an important part to understand in NodeJS. Max Ogden Blogotronz suggests that callbacks are used almost everywhere in Node [2]. They are, however, difficult to grasp at first.

Callbacks revert the call tree in the sense that it is impossible to return a value from an asynchronous function in the "traditional" style. Instead, we have to call the function awaiting our data when the data is ready - and a callback is just the way to do it[3]!

Some advise using Promises as the simplest substitute for obtaining a value from an asynchronous function [4]. A good introduction to the promise mechanism can be found here written by Will Timpson.

Listing object properties

var keys = Object.keys(myObject);

OOP in JavaScript

OOP principles, like encapsulation, can be applied in JavaScript too. An example can be seen in comparing the var and let keyword meanings as done by MDN here.

Reusing modules in a non-apocalyptic way

Arnaud Rinquin writes about this topic in an excellent way here.

Arnaud discusses that you can easily reuse your Node modules without publishing them, and using neither private modules nor even hosting your modules in a separate git repo [5].

CDNs for third-party libraries are discouraged

See here for details.

Afterword

The count of subtleties in ES6 (ECMAScript 6) seems to call for a guide named "ECMAScript for C/C++ programmers: A WTF-Driven Guide"


  1. JavaScript function parameters ↩︎

  2. Callbacks by Max Ogden Blogotronz ↩︎

  3. Impossible to "return" a value in the traditional sense from an asynchronous function ↩︎

  4. Use a Promise ↩︎

  5. Build modular application with npm local modules ↩︎