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.