Function-related


Function types


Regular functions

function myFunct(para1, para2, ..., paraN) { ... }

Function expressions

The main difference between a function expression and a regular function is the function name, which can be omitted in function expressions to create anonymous functions. A function expression can be used as a IIFE (Immediately Invoked Function Expression) which runs as soon as it is defined.

// Anonymous
var foo = function(para1, para2, ..., paraN) { ... }

// Named
var foo = function myFunct(para1, para2, ..., paraN) { ... }

Immediately-invoked function expressions

IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

// Anonymous
(function() {
    ...
})();

// Named
(function myFunct() {
    ...
})();

// Assigning the IIFE to a variable does not store it but its result.
var result = (function() {
    ...
})();

Higher-order functions

A function that returns another function or takes other functions as arguments is known as higher-order function.

// Higher-order function that returns another function
function myFunct(para1, para2, ..., paraN)
    ...
    return function() {
        ...
    };
}

// Higher-order function that takes other functions as arguments
function myFunct(para1, para2, ..., paraN) {
    ...
}

Callback functions

A function that is passed as an argument into another function is called a callback function.

// Higher-order function
function myFunct(callback) {
    ...
}

// Callback function
function myCallback() {
    ...
}

myFunct(myCallback);

Object methods

A JS method is a function that is encapsulated within an object. Every method is actually a property containing a function definition.

// 'bio' object
var bio = {
    'name': 'Marios Sofokleous',
    'role': 'Web Developer',
    'age': '27'
};

// Object method
bio.display = function() {
    console.log(bio.name + ', ' + bio.role + ', ' + bio.age);
}

// Invoke method
bio.display(); // 'Marios Sofokleous, Web Developer, 27'

Example 1: Display the mouse coordinates click anywhere on the page

//Empty array
var clickLocations = [];

// Regular function
function logClicks(x, y) {
    clickLocations.push({x: x, y: y});
    console.log('x location: ' + x + '; y location: ' + y);
}

// 'document' refers to the entire web page (DOM)
//
// The anonymous function that gets passed into the .addEventListener() method
// is called an event handler and runs every time a user clicks on the page.
//
// Sometimes inside an event handler function you might see a parameter
// specified with a name such as 'event', 'evt', or simply 'e'. This is called the
// event object, and it is automatically passed to event handlers to provide
// extra features and information. In our case, the event object gives us
// information regarding the coordinates of the mouse pointer.
document.addEventListener('click', function(e) {
    logClicks(e.screenX, e.screenY);
});

The result after some clicks would be like:

x location: 385; y location: 762
x location: 39; y location: 39
x location: 21; y location: 30
x location: 6; y location: 1515
x location: 352; y location: 1522

Example 2: Return statements

// String
var str = 'Marios Peter Andrew John';

// The split() function returns an array of strings
var names = str.split(' '); // ['Marios', 'Peter', 'Andrew', 'John']

Example 3: Return statements

// 'work' object
var work = {
    'jobs': [{
            'employer': 'Google',
            'title': 'Web developer',
            'location': 'California, USA',
            'dates': 'Feb 2014 - Current'
        },
        {
            'employer': 'Yandex',
            'title': 'Software Engineer',
            'location': 'Moscow, Russia',
            'dates': 'May 2013 - Jan 2014'
        }
    ]
};


// The locationizer function takes in the 'work' object and returns an array of
// the locations in the object
function locationizer(work_obj) {
    // Empty array
    var locations = [];

    for(var job of work_obj.jobs) {
        locations.push(job.location);
    }

    // Return 'locations' array
    return locations;
}

console.log(locationizer(work)); // ['California, USA', 'Moscow, Russia']

Example 4: Internationalized name format

The inName() function replaces the original name stored in bio object with an international version. Then it updates the DOM accordingly.

HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <title>Basic JS</title>
    </head>
    <body>
        <h1 id='fullName'></h1>
        <!-- Execute JavaScript when a button is clicked -->
        <button type='button' onclick='inName();'>
            Click to internationalize your name
        </button>
        <!-- This script runs when the page loads (jQuery) -->
        <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
        <!-- This script runs when the page loads (main.js) -->
        <script src='main.js'></script>
        <!-- This script runs only when the button is clicked (Click event) -->
        <script>
          function inName() {
              // Extract and capitalize first character (first name)
              var char = bio.name.slice(0, 1);
              char = char.toUpperCase();

              // Full name (array)
              var fullName = bio.name.split(' ');
              // First name to lower case
              fullName[0] = fullName[0].toLowerCase();
              // Last name to upper case
              fullName[1] = fullName[1].toUpperCase();

              // Format first name accordingly
              fullName[0] = char + fullName[0].slice(1);

              // Change value stored in the bio object
              bio.name = fullName[0] + ' ' + fullName[1];

              // jQuerry's replaceWith() method that replaces the content of
              // the selected element(s)
              $('#fullName').replaceWith('<h1>' + bio.name + '</h1>');
          }
        </script>
    </body>
</html>

JavaScript

// bio object
var bio = {
    'name': 'Marios Sofokleous',
    'role': 'Web Developer'
};

// jQuerry's append() method that inserts content to the end of the selected
// element(s).
$('#fullName').append(bio.name);

Result

Example 5: Alphabetizer

The alphabetizer() function takes in a names array in 'firstname lastname' format and returns an alphabetized array of names in 'lastname firstname' format.

// Input array
const names = [
    'Waylon Dalton',
    'Justine Henderson',
    'Abdullah Lang',
    'Marcus Cruz',
    'Thalia Cobb',
    'Mathias Little',
    'Eddie Randolph',
    'Angela Walker'
];

function alphabetizer(names) {
    // Alphabetized array
    var newArray = [];

    // Write names in lastname, firstname format
    var parsedName;
    for(let name of names) {
        parsedName = name.split(' '); // parsedName = ['Marios', 'Sofokleous']
        newArray.push(parsedName[1] + ' ' + parsedName[0]);
    }

    // Sort the elements in place
    newArray.sort();

    // Return the alphabetized array
    return newArray;
}

// Output array
const namesSorted = alphabetizer(names);

console.log(namesSorted);
// ['Cobb Thalia', 'Cruz Marcus', 'Dalton Waylon', 'Henderson Justine', 'Lang Abdullah', 'Little Mathias', 'Randolph Eddie', 'Walker Angela']

Variable scope


Introduction

Unlike C, and the rest of the C family, JavaScript includes function-level scope, which means that variables declared within a function are only available inside that function.

Examples

Example 1

// Global variable
var outsideExample1 = 'First string';

function example() {
    // A new local variable is created
    var outsideExample1 = 'Second string';
}

example();

console.log(outsideExample1); // 'First string'

Example 2

// Global variable
var outsideExample2 = 'First string';

function example() {
    // The value of outsideExample2 is overwritten
    outsideExample2 = 'Second string';
}

example();

console.log(outsideExample2); // 'Second string'

Example 3

// Global variable
var foo = 1;

// Only functions create new scopes
function alpha() {
    // A new local 'foo' is created
    var foo = 10;
    alert(foo); // 10
}

alpha(); // 10

alert(foo); // 1

// Blocks do not create new scopes
if (true) {
    // The value of global 'foo' is overwritten
    var foo = 5;
}

alert(foo); // 5

// To create a temporary scope within a block, do the following:
if (true) {
    // IIFE
    (function() {
        // A new local 'foo' is created
        var foo = 6;
        alert(foo); // 6
    }());
}

alert(foo); // 5

const, let or var?

var has global and functional scope while const and let have block scope. Do not use const if you weren't meaning to declare a constant. Once a variable has been declared using const it cannot be redeclared or reassigned. Also const variables must be declared with an initial value.

Example 1: 'const' cannot be redeclared or reassigned

const foo = 'marios';
foo = 'helen';
// Uncaught TypeError: Assignment to constant variable.

Example 2: 'const' cannot be redeclared or reassigned

const foo = {name: 'marios'};
foo = {name: 'helen'};
// Uncaught TypeError: Assignment to constant variable.

// Bare in mind that object keys and values are not protected
foo.name = 'helen';
// 'helen'
foo.age = 40;
// 40

Example 3: 'const' variables must be declared with an initial value

var x;
let y;
const z;
// Uncaught SyntaxError: Missing initializer in const declaration

Hoisting


Introduction

Hoisting is JavaScript's default behavior of moving declarations to the top. Only declarations are hoisted, not initializations.

Examples

Example 1

x = 5;
var y = x + 10;
var x;
var z = y + 2;
var x, y, z;
x = 5;
y = x + 10;
z = y + 2;

Example 2

var x = 2;
var y = 3;
alert('x = ' + x);
alert('y = ' + y);
var x, y;
x = 2;
y = 3;
alert('x = ' + x); // 'x = 2'
alert('y = ' + y); // 'y = 3'

Example 3

var x = 2;
alert('x = ' + x);
alert('y = ' + y);
var y = 3;
var x, y;
x = 2;
alert('x = ' + x); // 'x = 2'
alert('y = ' + y); // 'y = undefined'
y = 3;

Example 4

var foo1 = function() {
    alert('2');
};

var foo2 = function() {
    alert('3');
};

The code above is actually interpreted like this:

var foo1, foo2;

foo1 = function() {
    alert('2');
};

foo2 = function() {
    alert('3');
};

Example 5

var foo1 = function() {
    alert('2');
};

console.log(typeof foo1);
console.log(typeof foo2);

var foo2 = function() {
    alert('3');
};

console.log(typeof foo2);

The code above is actually interpreted like this:

var foo1, foo2;

foo1 = function() {
    alert('2');
};

console.log(typeof foo1); // function
console.log(typeof foo2); // undefined

foo2 = function() {
    alert('3');
};

console.log(typeof foo2); // function

Example 6

For regular functions (i.e. function myFunct( para1, para2, ..., paraN) { ... }), both the function declaration and definition (the actual instructions inside the function) get hoisted.

function foo1() {
    alert('2');
};

console.log(typeof foo1);
console.log(typeof foo2);

function foo2() {
    alert('3');
};

The code above is actually interpreted like this:

function foo1() {
    alert('2');
};

function foo2() {
    alert('3');
};

console.log(typeof foo1); // function
console.log(typeof foo2); // function

To avoid bugs, always declare all variables at the beginning of every scope. You should have exactly one var statement per scope, and that it be at the top. If you force yourself to do this, you will never have hoisting-related confusion.

Ad1
advertisement
Ad2
advertisement
Ad3
advertisement
Ad4
advertisement
Ad5
advertisement
Ad6
advertisement