Functions are pleasant in ES6

ES6 functions can offer a lot to JavaScript developers. Existing JS(ES5) functions have few glitches which make us write some non-idiomatic code. But syntactically and functionally ES6 added few more handy constructs and concepts. Here I discuss more attracting ES6 features which give us the instant advantage.

Arrow Functions (=>)

Arrow functions are shorthand notations of the JavaScript functions. For python developers they are lambdas. In JS ES5 standard, arrow functions are anonymous one liners. Arrow functions allow us to reduce the obvious code.

let add = function(a, b){

return a + b

}

Now translating it to ES6 arrow function.

let add = (a, b) => a + b # add(2,3) now returns 5

So what if we need to define a multi-line function.

let processAndAdd = ((a, b) => {

console.log("Processing....")

return a + b

})

The “new.target” Meta Property of a Function

Confusingly JavaScript functions can be used to for calling and as well as for creating objects. So a function can

call

construct

function Student(ID) {

this.id = ID

} // function usage can be like these two let naren = Student(1234) # stores undefined

let sriman = new student(1234) # stores Student{id: 1234}

So how to decide when a function is acting as a function and when it is acting as an object creator. In ES5 we use isinstanceof to check like this.

function Student(ID) {

if (this instanceof Student) {

this.id = ID; // using new

} else {

throw new Error("You must use new with Person.")

}

}

It is like forcing a developer to make Student function to create new students. In ES6 we got a new meta property called new.target

function Student(ID) {

if (typeof new.target !== "undefined") {

this.id = ID; // using new

} else {

throw new Error("You must use new with Person.")

}

}

The “name” Property of a Function

ES6 introduces a new property called name for each and every function we declare. This is to remove the ambiguity of identifying the functions.

let add = function(a, b) {

return a + b;

} function sub(a, b){

return a - b

} console.log(add.name) // Prints "add"

console.log(sub.name) // Prints "sub" let sum = add console.log(sum.name) // Prints "add" not "sum"

If we observe the genuine function name didn’t get lost. We can track the original function using the name property.

Block Level Declarations of a Function

In ES3, a block level function is technically a syntax error but browsers supported them. In the ES5 strict mode, it is illegal too. It is a better practice not to define a function in the block like this.

"use strict"; if (true) { // throws a syntax error in ES5 function blockFunction() {

console.log("This function is not allowed in ES5 strict mode");

}

}

In ES6, this kind of declarations are treated as block-level functions and their scope is limited to that particular block.

"use strict"; if (true) { // Perfectly valid in ES6 function blockFunction() {

console.log("This function is not allowed in ES5 strict mode");

}

} console.log(typeof blockFunction) // Not available. prints "undefined"

Note: If we remove the “use strict” function is available outside even in ES6.

Default Parameter Expressions in ES6 functions

We usually pass arguments to the JavaScript functions. But what if we need to provide optional arguments. ES5 provides a hacky way of passing default parameters.

// In ES5

function point(x, y){

x = x || 0

y = y || 0

return [x,y]

}

For more careful handling of non-passing arguments we can check for “undefined” and then populate a default value. ES6 removes this thing. It provides Python style default arguments.

// In ES6

function point(x = 0, y = 0){

return [x,y]

} point() // returns [0,0]

point(3) // returns [3,0]

point(10,12) //returns [10,12]

Note: Remember the order of arguments is not entertained by a JS function. The function simply returns undefined.

function Volume(length, breadth = 1, height){

return length * breadth * height

} Volume(2,3) // returns NaN because 2 * 3 * undefined => NaN

Rest Parameters in ES6

In order to accept a unknown number of arguments, ES6 provides a way to collect the arguments.

function Volume(...args){

let result = 1;

for (i of args){

console.log(i)

}

} Volume(1,2,3) // Prints 1

2

3

The same thing we can achieve in ES5 too.

function Volume(){

var result = 1;

for (i of arguments){

console.log(i)

}

} Volume(1,2,3) // Prints 1

2

3

using arguments is not helpful because it constitutes all arguments. We need to logically separate them by iterating over them. But using rest parameters(…args) we can have any number of default arguments along with uncertain extra arguments.

Note: Always rest parameters(…) should be declared only once and it should be the last argument in the function parameters.

Spread operator in ES6

When we need to pass an array as arguments to the function, we always index them manually. It is a lengthy process when we have a lengthy array.

function arrayContents(...args){

for (let i of args){

console.log(i)

}

} let myArray = [1,2,3] // Without spread operator

arrayContents(myArray[0], myArray[1], myArray[2]) // With spread syntax

arrayContents(...myArray)

It is similar to rest parameters (…) syntax but usage place is different.

There are much more low-level features in ES6. But I think this information is critical in learning about functions in ES6. If you have any query please comment and also can tweet here. https://twitter.com/Narenarya3