The following list of features is frequently used to attribute the functional languages12:

• Higher-order functions - the functions that take other functions as their arguments;
• Purity - absence of side effects;
• Recursion - availability of tail-call optimisation.

The high-order functions was in JavaScript since the beginning3. The arrow function syntax, introduced in ECMAScript 64, allowed to write the function constructs more easily and improved readability of the code. The iterative array methods5 (forEach, map, reduce, etc) eliminated necessity of mutating loop counter (index) to go through the lists. const6 added concept of "readonly" variables. Readonly properties7 made immutable records possible. Generators and improved iterators8 provided a way to create immutable iterable data sets. The most recent addition to the set of functional features is optimisation of tail recursion9, now available in some of JS engines10.

Although it was possible to create pure functions in earlier JS versions, the recent additions to the language added methods to create immutable data structures and provided ways to avoid using mutable variables for basic operations.

// toInt is a pure function that converts strings
// to integers. It does it by partially applying
// parseInt function, fixing its second argument.
let toInt = x => parseInt(x, 10);

// apply is a high-order pure function
let apply = (f, x) => f(x);

// it applies the first argument to the second
apply(toInt, "16"); // 16 (integer)


References