Skip to content

b

JavaScript

During the course, we have a goal and a need to learn a sufficient amount of JavaScript in addition to web development.

JavaScript has advanced rapidly in the last few years and in this course, we use features from the newer versions. The official name of the JavaScript standard is ECMAScript. At this moment, the latest version is the one released in June of 2023 with the name ECMAScript®2023, otherwise known as ES14.

Browsers do not yet support all of JavaScript's newest features. Due to this fact, a lot of code run in browsers has been transpiled from a newer version of JavaScript to an older, more compatible version.

Today, the most popular way to transpile is via Babel. Transpilation is automatically configured in React applications created with Vite. We will take a closer look at transpilation in part 7 of this course.

Node.js is a JavaScript runtime environment based on Google's Chrome V8 JavaScript engine and works practically anywhere - from servers to mobile phones. Let's practice writing some JavaScript using Node. It is expected that you have both versions of node installed as directed in the install Node section of Part 0

The code is written into files ending with .js that are run by issuing the command node name_of_file.js

It is also possible to write JavaScript code into the Node.js console, which is opened by typing node in the command line, as well as into the browser's developer tool console. The newest revisions of Chrome handle the newer features of JavaScript pretty well without transpiling the code. Alternatively, you can use a tool like JS Bin.

JavaScript can be reminiscent, both in name and syntax, of Java. But when it comes to the language's core, they could not be more different. Coming from a Java background, the behavior of JavaScript can seem a bit alien, especially if one does not make the effort to look up its features.

In certain circles, it has also been popular to attempt "simulating" Java features and design patterns in JavaScript. We do not recommend doing this as the languages and their ecosystems are ultimately very different.

Variables

In JavaScript there are a few ways to go about defining variables:

const x = 1
let y = 5

console.log(x, y)   // 1, 5 are printed
y += 10
console.log(x, y)   // 1, 15 are printed
y = 'sometext'
console.log(x, y)   // 1, sometext are printed
x = 4               // causes an error

The keyword const does not define a variable but a constant for which the value can no longer be changed. On the other hand, the keyword let defines a normal variable.

In the example above, we also see that the variable's data type can change during execution. At the start, y stores an integer; at the end, it stores a string.

It is also possible to define variables in JavaScript using the keyword var. var was, for a long time, the only way to define variables. const and let were only recently added in version ES6. In specific situations, var works differently compared to variable definitions in most languages - see JavaScript Variables - Should You Use let, var or const? on Medium or Keyword: var vs let on JS Tips for more information. During this course, you should only use const and let! Avoid var as if it tested positive for COVID. You can find more on this topic on YouTube - e.g. var, let and const - ES6 JavaScript Features

let const meme

Arrays

Here we provide some information on arrays and a couple of examples of their use:

const profits = [1, -1, 3]

profits.push(5)

console.log(profits.length) // 4 is printed
console.log(profits[1])     // -1 is printed

profits.forEach(value => {
  console.log(value)  // numbers 1, -1, 3, 5 are printed, each on its own line
})                    

Notable in this example is the fact that the contents of array profits can be modified even though it is defined as a const. Because the array profits is an object, it always points to the same object. However, the content of profits changes as new items are added to it.

One way of iterating through the items of the array is using forEach as seen in the example. forEach receives a function defined using the arrow syntax as a parameter.

value => {
  console.log(value)
}

forEach calls the function for each of the items in the array, always passing the individual item as an argument. The function as the argument of forEach may also receive other arguments.

In the previous example, a new item was added to the array using the method push. When using React, techniques from functional programming are often used. One characteristic of the functional programming paradigm is the use of immutable data structures. In React code, it is preferable to use the method concat, which creates a new array with the added item, leaving the original array unchanged.

const profits = [1, -1, 3]

const newProfits = profits.concat(5)  // creates new array

console.log(profits)  // [1, -1, 3] is printed
console.log(newProfits) // [1, -1, 3, 5] is printed

The expression profits.concat(5) does not add a new item to the old array. Instead, concat returns a duplicate with the new item added in.

There are plenty of useful methods defined for arrays. Let's look at a short example of using the map method.

const profits = [1, 2, 3]

const doubledProfits = profits.map(value => value * 2)
console.log(doubledProfits)   // [2, 4, 6] is printed

Based on the old array, map creates a new array, for which the function given as a parameter is used to create the items. In the case of this example, the original value is multiplied by two.

map can also transform the array into something completely different:

const profitsHTML = profits.map(value => '<li>' + value + '</li>')
console.log(profitsHTML)  
// [ '<li>1</li>', '<li>2</li>', '<li>3</li>' ] is printed

Here an array filled with integer values is transformed into an array containing strings of HTML using the map method. In part 2 of this course, we will see that map is used quite frequently in React.

Individual items of an array are easy to assign to variables with the help of the destructuring assignment.

const ratings = [1, 2, 3, 4, 5]

const [first, second, ...rest] = ratings

console.log(first, second)  // 1, 2 is printed
console.log(rest)          // [3, 4, 5] is printed

Thanks to the assignment, the variables first and second will receive the first two integers of the array as their values. The remaining integers are collected into an array of their own which is then assigned to the variable rest.

Objects

There are a few different ways of defining objects in JavaScript. One popular way is by using object literals, which happens by listing its properties within braces:

const object1 = {
  name: 'Powercat',
  performances: 23,
  team: 'Tigers',
}

const object2 = {
  name: 'COMP 227',
  level: 'graduate',
  units: 3,
}

const object3 = {
  name: {
    first: 'Randy',
    last: 'Lau',
  },
  grades: [2, 3, 5, 3],
  department: 'Stanford University',
}

The values of the properties can be of any type, like integers, strings, arrays, objects...

The properties of an object are referenced by using the "dot" notation, or by using brackets:

console.log(object1.name)         // Powercat is printed
const fieldName = 'team' 
console.log(object1[fieldName])    // Tigers is printed

You can also add properties to an object dynamically by using the same notation.

object1.address = 'University of the Pacific'
object1['student ID'] = 989123456

Keep in mind that properties that contain spaces must use brackets, as object1.student ID will not compile.

The computer cannot determine if the property is named student ID or just student

Naturally, objects in JavaScript can also have methods. However, during this course, we do not need to define any objects with methods of their own. This is why they are only discussed briefly during the course.

Objects can also be defined using so-called constructor functions, which results in a mechanism reminiscent of many other programming languages, e.g. Java's classes. Despite this similarity, JavaScript does not have classes in the same sense as object-oriented programming languages. There has been, however, an addition of the class syntax starting from version ES6, which in some cases helps structure object-oriented classes.

Functions

We have already become familiar with defining arrow functions. The complete process, without cutting corners, of defining an arrow function is as follows:

const sum = (n1, n2) => {
  console.log(n1)
  console.log(n2)
  return n1 + n2
}

and the function is called as can be expected:

const result = sum(1, 5)
console.log(result)

If there is just a single parameter, we can exclude the parentheses from the definition:

const square = num => {
  console.log(num)
  return num * num
}

If the function only contains a single expression then the braces are not needed. In this case, the function only returns the result of its only expression. Now, if we remove console printing, we can further shorten the function definition:

const square = num => num * num

This form is particularly handy when manipulating arrays - e.g. when using the map method:

const ratings = [1, 2, 3]
const ratingsSquared = ratings.map(r => r * r)
// ratingsSquared is now [1, 4, 9]

The arrow function feature was added to JavaScript only a couple of years ago, with version ES6. Before this, the only way to define functions was by using the keyword function.

There are two ways to reference the function via the old way.

function declaration function expression
function subtract(a, b) {
return a - b
}

const result = subtract(6, 2)
// result is now 4
const subtract = function(a, b) {
return a - b
}

const result = subtract(6, 2)
// result is now 4

In the function expression case, there is no need to give the function a name and the definition may reside among the rest of the code:

During this course, we will define all functions using the arrow syntax, which means that the above function would be:

const product = (n1, n2) => {
    return n1 * n2
}

const result = product(2, 6)

Object methods and "this"

Because this course uses a version of React containing React Hooks we do not need to define objects with methods. However, when using older versions of React one must understand how the keyword this works.

The keyword this is not as relevant to the course but is valuable if you want to understand Javascript and plan to continue with web development. Expect to be asked about it at a Javascript coding interview.

this, which refers to the object itself, is commonly misunderstood. For example, this behaves differently when used in arrow functions versus others that use the function() keyword.

Let's go through an example.

We can assign methods to an object by defining properties that are functions:

const mascot = {
  name: 'Powercat',
  performances: 23,
  team: 'Tigers',
  cheer: function() {    console.log('GO ', this.team, '!')  },}

mascot.cheer()  // "Go Tigers!" gets printed

Methods can be assigned to objects even after the creation of the object:

const mascot ={
  name: 'Powercat',
  performances: 23,
  team: 'Tigers',
  cheer: function() {
    console.log('GO ', this.team, '!')
  },
}

mascot.perform = function() {  this.performances += 1}
console.log(mascot.performances)   // 23 is printed
mascot.perform()
console.log(mascot.performances)   // 24 is printed

Let's slightly modify the object:

const mascot ={
  name: 'Powercat',
  performances: 23,
  team: 'Tigers',
  cheer: function() {
    console.log('GO ', this.team, '!')
  },
  taunt: function(opponent) {    console.log('Boo ', opponent, '!')  },}

mascot.taunt('Bulldogs')        // Boo Bulldogs! is printed

const referenceToTaunt = mascot.taunt
referenceToTaunt('Bears')   // Boo Bears! is printed

Now the object has the method taunt which taunts the opposing word given to it as parameters. The method is called in the usual way, using the object mascot.taunt('Bulldogs') or by storing a method reference in a variable and calling the method through the variable: referenceToTaunt('Bears').

If we try to do the same with the method cheer we run into an issue:

mascot.cheer()       // prints "Go Tigers!"

const referenceToCheer = mascot.cheer
referenceToCheer()   // prints "Go undefined!"

When calling the method through a reference, the method loses knowledge of what the original this was. Contrary to other languages, in JavaScript the value of this is defined based on how the method is called. When calling the method through a reference, the value of this becomes the so-called global object and the result is often not what the software developer had originally intended.

Losing track of this when writing JavaScript code brings forth a few potential issues. Situations often arise where React or Node (or more specifically the JavaScript engine of the web browser) needs to call some method in an object that the developer has defined. However, in this course, we avoid these issues by using "this-less" JavaScript.

One situation leading to the "disappearance" of this arises when we set a timeout to call the cheer function on the mascot object, using the setTimeout function.

const mascot = {
  name: 'Powercat',
  team: 'Tigers',
  cheer: function() {
    console.log('GO ', this.team, '!')
  },
}

setTimeout(mascot.cheer, 1000)

As mentioned, the value of this in JavaScript is defined based on how the method is being called. When setTimeout is calling the method, it is the JavaScript engine that calls the method and, at that point, this refers to the global object.

There are several mechanisms by which the original this can be preserved. One of these is using a method called bind:

setTimeout(mascot.cheer.bind(mascot), 1000)

Calling mascot.cheer.bind(mascot) creates a new function where this is bound to point to Powercat, independent of where and how the method is being called.

Using arrow functions it is possible to solve some of the problems related to this. They should not, however, be used as methods for objects because then this does not work at all. We will come back later to the behavior of this and arrow functions.

If you want to gain a better understanding of how this works in JavaScript, the Internet is full of material about the topic, e.g. the screen-cast series Understand JavaScript's this Keyword in Depth by egghead.io is highly recommended!

Classes

As mentioned previously, there is no class mechanism in JavaScript like the ones in object-oriented programming languages. There are, however, features to make "simulating" object-oriented classes possible.

Let's take a quick look at the class syntax that was introduced into JavaScript with ES6, which substantially simplifies the definition of classes (or class-like things) in JavaScript.

In the following example, we define a "class" called Fan and two Fan objects:

class Fan {
  constructor(name, team) {
    this.name = name
    this.team = team
  }
  cheer() {
    console.log('GO ', this.team, '!')
  }
}

const stephen = new Fan('Stephen Colbert', 'Cougars')
stephen.cheer()

const osvaldo = new Fan('Too Hard to Pronounce', 'Roots')
osvaldo.cheer()

When it comes to syntax, the classes and the objects created from them are very reminiscent of Java classes and objects. Their behavior is also quite similar to Java objects. At the core, they are still objects based on JavaScript's prototypal inheritance. Both objects are explicitly of the type Object, since JavaScript essentially only defines the types Boolean, Null, Undefined, Number, String, Symbol, BigInt, and Object.

The introduction of the class syntax was a controversial addition. Check out Not Awesome: ES6 Classes or Is “Class” In ES6 The New “Bad” Part? on Medium for more details.

The ES6 class syntax is used a lot in "old" React and also in Node.js, hence an understanding of it is beneficial even in this course. However, since we are using the new Hooks feature of React throughout this course, we have no concrete use for JavaScript's class syntax.

JavaScript materials

There exist both good and poor guides for JavaScript on the Internet. Most of the links on this page relating to JavaScript features reference Mozilla's JavaScript Guide.

It is highly recommended to immediately read A Re-introduction to JavaScript (JS tutorial) on Mozilla's website.

If you wish to get to know JavaScript deeply there is a great free book series on the Internet called You-Dont-Know-JS.

Another great resource for learning JavaScript is javascript.info.

The free and highly engaging book Eloquent JavaScript takes you from the basics to interesting stuff quickly. It is a mixture of theory projects and exercises and covers general programming theory as well as the JavaScript language.

Namaste 🙏 JavaScript is another great and highly recommended free JavaScript tutorial that explains how JS works under the hood. Namaste JavaScript is a pure in-depth JavaScript course released for free on YouTube. It will cover the core concepts of JavaScript in detail and everything about how JS works behind the scenes inside the JavaScript engine.

egghead.io has plenty of quality screen-casts on JavaScript, React, and other interesting topics. Unfortunately, some of the material is behind a paywall.