12 common JavaScript questions answered

JavaScript is a fantastic, flexible web design tool, as our top examples of JavaScript article shows. But even with the biggest of tools, there's always more to learn and discover.

Here are 12 questions (and answers) about JavaScript that have left many developers stumped – even experienced JavaScript coders. 

On this page we run through common questions and answers, including those often trotted out in job interviews. On the next page, we take a more in-depth look at two more complex areas: How to use JavaScript to improve site performance, and how to future-proof JavaScript code.

01. What is prototypical inheritance and how useful is it?

In JavaScript, almost everything is an object. Every object has a prototype, from which it inherits values and behaviours. If an object doesn't include a property that's being requested, JS will look for it inside its prototype instead. It carries on up the chain of prototypes until it finds a match, or returns an error.

This is useful when making objects that share the same values and operations. By having these live on a prototype, only one copy of them needs to exist, making projects memory efficient.

var parent = {inherit: true}
var childA = Object.create(parent);
var childB = {};
Object.setPrototypeOf(childB, parent);
class childC extends parent {}

Prototypes can be added to objects on creation using Object.create(), or after with Object.setPrototypeOf(). ES2015 has a 'class' keyword that, when used with 'extends', will use that value as its prototype.

02. How can JavaScript be used to improve accessibility on the web?

It is common for modern web accessibility tools to be able to handle JavaScript and dynamic content. It can be used to help these technologies as long as it is used as an enhancement rather than required to function.

A common way to assist users is to provide useful focus management. A calendar, for example, should be able to cycle through days using the arrow keys, with up and down keys skipping a week at a time. It is just a case of listening for keyboard events while focus is within that component.

Important data changing as a result of JavaScript, for example form feedback, should also be announced for screen readers. Often this is achieved by marking up a container as a live region.

03. What is event bubbling and how is it different to event capturing?

Event delegation is a technique that uses event bubbling to its advantage. By adding a listener to a parent element, developers are alerted to events for any of its children

Both event capturing and bubbling are both part of a process called 'event propagation', where browsers respond to events happening on the page. Older browsers used to do one or the other, but nowadays they all do both. 

The first phase – the capturing phase – occurs as soon as an event happens. It starts at the topmost level, which is either 'document' or 'window' depending on the event. From there it goes through <html> and whatever lives inside it until it reaches the element the event occurred within.

The second phase – the bubbling phase – then happens. It repeats the process but in reverse, beginning with the element the event was triggered by and 'bubbling' to the topmost <html> element. When adding event listeners, this is the default.

04. How does event delegation improve code on sites with lots of interactive elements?

Websites often have lots of dynamic content regularly changing on the page. If these elements need to be interactive, these would need some kind of event listener picking up those interactions. If each element required its own listener, this would clutter up code and increase what the browser needs to keep track of.

Event delegation is a technique that uses event bubbling to its advantage. By adding a listener to a parent element, developers are alerted to events for any of its children.

parentEl.addEventListener('click', function(e) {
  if(e.target && e.target.nodeName == 'BUTTON') {
  // Button clicked
  } });

Inside the event callback, the original target of that event will always be the 'target', which can be used to decide what to do next. For example, a data attribute could hold an ID to reference an object property.

05. What are closures and how can they be useful in organising code?

Functions in JavaScript use what is called the 'lexical environment', meaning it has access to variables defined outside, but those defined inside can only be accessed within.

function outer() {
  let x = 'Web Designer';
  function shout() {
  alert(`I love ${x}!`);
  }
  shout(); }

Calling outer() will show 'I love Web Designer!', but if 'shout' or 'x' are referenced outside of outer(), both will be undefined. A closure is a combination of a function alongside its lexical environment. In this case, the closure is the 'outer' function.

These are useful when creating multiple components, as anything declared inside will not affect others. They can be used to create private functions and variables in a similar way to other object-oriented languages like Python. The module pattern uses closures extensively to provide structured ways for modules to interact. 

06. What does 'use strict' mean at the top of a block of code?

ES5 introduced an optional variant of JavaScript called 'strict mode'. In strict mode, quirks of earlier versions would throw errors rather than result in unintended behaviour.

function strictFunction() {
  'use strict';
  myVar = 4; //ReferenceError }

Above we are accessing a variable that doesn't exist. Outside of strict mode, this would instead add myVar to the global scope, which if we were not careful could completely overwrite functionality defined earlier in the script. In strict mode, this throws an error and halts any destruction. ES2015 modules are in strict mode by default, but in closures created with functions, 'use strict' can be applied at a function level as well as an entire file. 

07. What does the term 'hoisting' mean in reference to JavaScript?

JavaScript is unique in that it does not need compiling before being distributed. A browser will compile scripts as it finds them and make notes of any functions and variables that are declared within. 

The browser then makes a second pass to execute the code, knowing where these functions and variables apply. As a block is executed, its function and variable declarations are 'hoisted' to the top of the block.

welcome("Matt"); //"Welcome, Matt."
function welcome(name) {
  return `Welcome, ${name}.`;
}

In this example, we are able to use the 'welcome' function as it is hoisted up to the top of the script.

08. What is the difference between an arrow function and a regular function?

ES2015 provided lots of changes and one to make an quick impact was arrow functions.

function CountUp() {
  this.x = 0;
  setInterval(() => console.log(++this.x), 1000); }
var a = new CountUp();

The key difference, despite being shorter to write, is that arrow functions do not create their own value for 'this'. They will instead use the value of the enclosing block. In the above example, this would log out 1, 2, 3, etc once every second. With a regular function, this.x would be undefined, so it would log NaN. The body of an arrow function is assumed to be the return value from it. This makes them useful for promises, where values are passed through. Regular functions must explicitly return a value, or will return undefined.

09. Where should I use the 'let' and 'const' keywords instead of 'var'?

Another fundamental change with ES2015 was the introduction of 'let' and 'const' as alternative ways to define variables. Variables declared in this way are limited to the block they were defined in. This provides more certainty that values created inside different blocks won't interfere with code outside.

for(let x=1; x<=3; x++) {
console.log(x); // 1, 2, 3}
console.log(x); // "x is not defined"

If the value of the variable will not change, use 'const' instead of 'let'. Errors are thrown when attempting to redefine a constant. Objects and array variables can still change internally, but are not completely replaced.

Both 'let' and 'const' do not get hoisted like 'var', so cannot be referenced before they are initialised. Between the start of the block and the initialisation is known as the 'temporal dead zone' and can often be a source of confusion.

10. What is functional programming and how is it different?

It is an alternative way of creating programs by passing application state exclusively through functions. By avoiding side effects, it's possible to develop code that's easy to understand.

Traditionally, JavaScript projects are built with an object-oriented structure. Information about the current state of the program is held within objects, which get updated as the page changes.

Functional programming provides a different way of thinking. While languages like F# have used it for a while now, ES2015 brought important methods to JavaScript that open this up to the web.

All work must be done inside 'pure' functions. These are functions that are not affected by any data outside the scope of that function. In other words, if the same values are supplied to the function, the same result will always be returned.

This also means that there can be no shared state between functions. Any state within an application that needs to be used should be passed as a parameter to a function, rather than accessed directly from it. 

Finally, code should avoid changing values after they are made. For example, each change of an object should return a copy of that object with the value changed. This is to avoid side effects, which can cause bugs and make code harder to test.

Next page: How can I use JS to improve the performance of my site? and How can I future-proof my JavaScript code?