JavaScript from 0 to infinity

If you already know how to program in another language, this will be a good reference page where you can quickly find out “how is X done in JavaScript“.

0- Variables

var carName = "Volvo";

 

Re-Declaring JavaScript Variables

If you re-declare a JavaScript variable, it will not lose its value.

var carName = "Volvo";
var carName;

var2 = carName;  // Now var2 equals "Volvo"

 

 

Let (ES6)

Similar to var but it’s only accessible in the block level it is defined.

let a = 50;
let b = 100;
if (true) {
  let a = 60;
  var c = 10;
  console.log(a/c); // 6
  console.log(b/c); // 10
}
console.log(c); // 10
console.log(a); // 50

 

 

Const (ES6)

Assign a constant value to the variable, the value cannot be changed later.

const a = 50;
a = 60; // shows error. You cannot change the value of const.

 

 

 

Arrays

const LANGUAGES = ['Js', 'Ruby', 'Python', 'Go'];
LANGUAGES = "Javascript"; // shows error.
LANGUAGES.push('Java'); // Works fine.

Since an array is a pointer to a memory address, adding items is ok because the address pointer remains constant.

 

 

Set (ES6)

Store a set of unique values.

var sets = New Set([1,5,6,8,9]);
sets.has(1); // Returns true.
sets.has(10); // Returns false.
sets.add('1'); // Duplicate value, will not be added.

 

 

Spread operator

Converts an array into a list of elements.

For example, ‘max’ requires a list of params like Math.max(12, 3, 5) , it does not accept an array.

let arr = [12, 3, 5];

Math.max(arr); // Fails, array not accepted
Math.max(...arr); // OK, equivalent to Math.max(12, 3, 5)

 

 

Equality comparations

These are a little peculiar in JavaScritp.

Strict equality using ===

If the values have different types, the values are considered unequal. They’re considered equal if they’re both not NaN and are the same value, or if one is +0 and one is -0.

Loose equality using ==

After converting both values to a common type (one or both sides may undergo conversions), an === is performed.

 

 

Concatenation or addition

Getting one or the other when using the + operator depends on the data types. The most common case, a string and a number, will result in concatenation.

 

 

Use the value of a variable as key in an object

var a = 'name'

const myObject = {
[a] : 'Jane'
};

 

 

Values or Reference?

This might look like a deeper aspect of the language, but soon enough you could encounter unexpected effects if not handled correctly.

Data types copied by value: Boolean, null, undefined, String, and Number.
Data types copied by reference: Array, Function, and Object. (So, every object)

If you write:

var a = [1, 2];
var b = a;

When you change b[0] = 3, a will also be modified because b is just a reference to the same memory address as a.

To compare two reference objects, if you use === it will only return true if they both point to the same object. It will return false even if the value is the same (that’s where you would use simply ==).

Impure functions can change the value of the objects passed to them as arguments. Since a reference is passed, the original memory location can be modified.

 

 

 

Strings and Templates

Strings are immutable, you can not replace a letter in a string. You can however reassign the variable or combine strings.

 

Template literals

They are enclosed by backticks (`). You don’t need to escape either double or single quotes inside them. Multiline strings are accepted.

Substitution

The most useful part is that you can put ${varName}  in your string template, and the content will be replaced with the value of varName.

let name = "Borja"
let message = `Hi, I'm ${friendsName}.`;

 

 

 

 

1- Conditional branching

These are present in most programming languages and are almost self-explanatory.

 

If

if (time < 10) {
  greeting = "Good morning";
} else if (time < 20) {
  greeting = "Good day";
} else {
  greeting = "Good evening";
}

 

Switch

var expr = 'Papayas';
switch (expr) {
  case 'Oranges':
    console.log('Oranges are $0.59 a pound.');
    break;
  case 'Mangoes':
  case 'Papayas':
    console.log('Mangoes and papayas are $2.79 a pound.');
    break;
  default:
    console.log('Sorry, we are out of ' + expr + '.');
}

 

While

while (i < 10) {
  text += "The number is " + i;
  i++;
}
do {
  text += "The number is " + i;
  i++;
}
while (i < 10);

 

For

for (i = 0; i < 5; i++) {
  text += "The number is " + i + "<br>";
}

 

For..in

Provides the index to iterate along the array. (x in the following example)

var person = {fname:"John", lname:"Doe", age:25};
var x;

for (x in person) {
  console.log( person[x] );
}

 

For..of (ES6)

Works like for..in but provides the value at every index of the array instead of the index.

let arr = ['a','b','c'];
for (let value of arr) {
  console.log(value);
}

 

 

 

 

2- Functions

The basic unit for code reuse.

function square(number) {
  return number * number;
}

a = square(2);

 

 

Arrow functions (ES6)

// Old Syntax
function old(a, b) {
// Do something
}
// New Syntax
var new = (a, b = 3) => {
// Do something
}

 

 

Static methods (ES6)

Allows calling a class function without creating an instance of the class.

class Example {
  static Callme() {
    console.log("Static method");
  }
}

Example.Callme();

 

 

Getters and Setters (ES6)

Instead of having to manually create and call getter and setter functions, defining them with the get, set keywords allows using the property as a normal property buy having the getters and setters called automatically.

class Car {
  constructor(brand) {
    this.brand = brand;
  }
  get Brand() {
    return this.brand;
  }
  set Brand(brand) {
    this.brand = brand;
  }
}

let myCar = new Car("Volvo"); // Constructor.
console.log(myCar.Brand); // Invokes getter.

myCar.Brand = "Tesla"; // Invokes setter.
console.log(myCar.Brand);

 

 

Functions are first class objects and they can be assigned to a variable and also be passed as a parameter.

const square_f = function (number) {
  return number * number;
}

a = square_f(2);

 

 

Pass an arbitrary number of parameter to a function

const sum = function (...args) {
  let result = 0;
  for(let i = 0; i < args.length; i++) {
    result += args[i];
  }
  return result;
}

“arguments” is a reserved keyword to reference the arguments passed. It’s not often used anymore, the … expansion is preferred.

 

 

Callbacks

You can pass a function to a function.

function dispatch (fn) {
  fn();
}

 

Most often used callbacks:

Timeout for delayed execution

setTimeout(function () {
  console.log('Check the status of some server...');
}, 1000);

Interval for repeated execution

setInterval(()=> {
  console.log("This will be executed every 5 seconds");
}, 5000);

Clearable interval

var myVar = setInterval(myTimer, 1000);

function myTimer() {
    var d = new Date();
    var t = d.toLocaleTimeString();
    document.getElementById("demo").innerHTML = t;
}

function myStopFunction() {
    clearInterval(myVar);
}

 

Function object methods

Since all functions are objects, they behave as such. Functions have the following methods:

 

Call

Allows changing the context (the meaning of the keyword this) where a method will be run. The first parameter to call method is the new context and the following parameters are the arguments for the method.

object.method.call(newContext, “Param1”, param2);

 

Apply

The only difference between call() and apply() is that the parameters for the method are passed as an array.

object.method.call(newContext, [“Param1”, param2]);

 

Bind

Returns a new method which will be bound to the passed context.

const newMethodNewContext = object.method.bind(newContext);

You can call newMethodNewContext( params ) and this will refer to newContext.

 

 

 

Constructor Function

This is a way to get object-oriented-like functionality in our code.

function User (name, email) {
this.name = name; // instance variables

// Methods defined here will be replicated per instance
this.fn = function () {
// Do sthing.
}
}

// PROTOTYPE: Recommended, not replicated, only one per object type
User.prototype.fnWithPrototype = function () {
// Do sthing.
}

 

Then, you can create an instance of the object with:

var user = new User('username');

 

 

Ternary operator

var a = true; //conditon

b = a ? 'Yes' : 'No';
a ? b = 'Yes' : b = 'No'; // These are equivalent.

 

 

Reduce

Add the result of executing a function on all the elements of an array.

array.reduce(function(total, currentValue, [currentIndex, arr]), [initialValue])
var numbers = [65, 44, 12, 4];

function getSum(total, num) {
return total + num;
}

function myFunction(item) {
finalResult = numbers.reduce(getSum);
}

 

 

Push / Pop

Add an item to the end of an object and return the new length / return the last one and remove it.

newLen = myArray.push('new')
lastItem = myArray.pop()

 

 

Splice

Add and/or remove elements of an array.

array.splice(fromIndex, itemsToDelete, [item1, item2])

ItemsToDelete is optional and can be zero and items are optional.

 

 

Foreach

Execute a function once on every element of an array. The return values are discarded.

var array1 = ['a', 'b', 'c'];

array1.forEach(function(element) {
console.log(element);
});

 

 

Map

Execute a function on all the elements of an array and store each result in a new array.

var array1 = [1, 4, 9, 16];

const map1 = array1.map(x => x * 2);

console.log(map1);
// Output: Array [2, 8, 18, 32]

Map is usually faster and generates a new array rather than modifying an existing one.

 

 

Find

Returns the value of the first element in the array that makes the provided function return true.

var array1 = [5, 12, 8, 130, 44];

var found = array1.find(function(element) {
return element > 10;
});

console.log(found); // Output: 12

You can use findIndex to get the index of the item instead.

 

 

Filter

Like find, but returns all matching elements.

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result); // Output: Array ["exuberant", "destruction", "present"]

 

 

Hoisting

In practical terms, this means that variable and function declarations are moved to the top of their containing scope.

In reality, this happens because the variable and function declarations are put into memory during the compile phase, but they stay exactly where you typed them in your coding.

Despite it may look strange, this works fine:

name = “Jane”;
var name;
console.log(name); // Prints “Jane”

However, only declarations are hoisted, assignments are not. Therefore this will fail:

console.log(name); // Prints “undefined”
var name = “Jane”;

 

In a similar way, function declarations are hoisted, but function expressions are not.

This works:

myFn();

function myFn() {
var name = “Jane”;
console.log(name);
}

But this won’t:

myFn(); // “TypeError : myFn is not a function”

var myFn = function () { // This is a function expression and therefore not hoisted
var name = “Jane”;
console.log(name);
}

In case you use the same name to declare a variable and a function (which shouldn’t really happen), note that hoisting is performed on functions before variables, unless the variable is assigned a value.

 

 

Closures

A more complex example would require changing a local variable inside a function from the outside. This can be done with a closure, it’s like giving functions private variables.

They are functions inside other functions. They have access to its own scope, the outer function’s variables and parameters, and the global variables.

var add = (function () {
var counter = 0;
  return function () {return counter += 1;}
})();

add();
add();
add(); // the counter is now 3

 

 

 

 

3- Asynchronous code

Async processes can be implemented in several ways in JS.

 

Promises

A promise has 3 states: pending, resolved, rejected. You ask a (usually long) process to run some code, it returns a Promise (it promises that it will give you the value when it finishes). If all is OK, it will be resolved, otherwise, it’ll be rejected.

 

Declaring a Promise

var myPromise = new Promise(function(resolve, reject) {

// Long job

if(/* good condition */) {
resolve('Success!');
}
else {
reject('Failed.');
}
});

Arrow sintax

const promise = new Promise((resolve, reject) => {
// Resolve or reject
});

 

Using it

myPromise.then(function() {
/* do something with the result you expected */
}).catch(function() {
/* act on the error */
})

 

 

Async/Await (ES6)

The same functionality can be much easier to write and handle. You have a function that returns a Promise, this is how you would normally use it:

const makeRequest = () =>
promiseFn()
.then(data => {
console.log(data)
return "done"
})

makeRequest()

Now you can make the handler function async, and use await to resume the execution when the promise resolves.

const makeRequest = async () => {
  console.log(await getJSON())
  return "done"
}

makeRequest()

The await keyword can only be used inside functions defined with async. Any async function returns a promise implicitly, and the resolve value of the promise will be whatever you return from the function (which is the string “done” in our case).

 

 

Combine values from several async functions

This is a mess when using regular Promise syntax, but it becomes much cleaner with await.

const makeRequest = async () => {
const value1 = await promise1()
const value2 = await promise2(value1)
return promise3(value1, value2)
}

 

 

 

Try / Catch

This can be used with any kind of code, but using async/await lets you catch errors that happen in both sync and async code (which is not the case with normal Promises, those have to be handled separately in .then and .catch).

const makeRequest = async () => {
try {
  // this parse may fail
  const data = JSON.parse(await getJSON())
  console.log(data)
} catch (err) {
  console.log(err)
}
}

 

Easier debugging

Debugging is more comfortable since you can set a breakpoint in lines containing await, that’s not possible in async code inside a Promise.

 

 

 

 

4- (this)

The this keyword has a different value depending on where it appears.

  • If the keyboard new is used, this refers to the newly created object.
  • As explained before, if using apply, call, or bind, it refers to the context that you pass.
  • If invoked outside the cases mentioned before, it refers to the global object.
  • Since a function is an object, you can have members in it. In that case, this would refer to them.

(ES6) In an arrow function, this refers to the code that contains the arrow function, it does not have it’s own this.