JavaScript Flashcards

Category sponsor

JavaScript is a versatile, dynamic programming language that is a fundamental part of modern web development. Initially created to add interactivity to static HTML pages, JavaScript has evolved into a powerful tool that can be used both on the client and server sides.

Our flashcard app includes 170 carefully selected JavaScript interview questions with comprehensive answers that will effectively prepare you for any interview requiring JS knowledge. IT Flashcards is not just a tool for job seekers - it's a great way to reinforce and test your knowledge, regardless of your current career plans. Regular use of the app will help you stay up-to-date with the latest JavaScript trends and keep your skills at a high level.

Sample JavaScript flashcards from our app

Download our app from the App Store or Google Play to get more free flashcards or subscribe for access to all flashcards.

What is lexical scope in JavaScript?

Lexical scope in JavaScript is a principle where the visibility range of a variable is determined by its location in the code. This means that variables are accessible inside the block in which they were defined, as well as in any nested blocks. This enables the creation of closures and control over variable access. Example of using lexical scope in JavaScript code:
function outerFunction() {
  let outerVariable = `I'm outside!`;

  function innerFunction() {
    console.log(outerVariable); // Has access to the 'outerVariable'
  }

  innerFunction();
}
outerFunction(); // Displays `I'm outside!`

Lexical scope allows an inner function to access variables defined in an outer function, even after the outer function has finished. This is a key element in creating closures in JavaScript, allowing for more flexible state management in applications.

What is hoisting?

Hoisting is a mechanism in JavaScript languages where variables and functions are moved to the top of their scope before the code is executed. In practice, this means that we can use functions or variables before they are actually declared.

However, it should be noted that hoisting works slightly differently for variables and functions.

For variables declared with var keywords, only the declaration is hoisted, not the initialization. Variables initialized before declaration will be returned as undefined.

An example of hoisting code for variables:
console.log(myVar); // undefined
var myVar = 5;
console.log(myVar); // 5

For functions, hoisting moves both the declaration and definition of the function to the top, which allows the use of the function before it's declared.

An example of hoisting code for functions:
console.log(myFunction()); // "Hello World"

function myFunction() {
  return "Hello World";
}

Hoisting does not occur for variables declared with let and const.

What is an arrow function and what are its advantages?

An arrow function, also known as arrow function, is a type of function introduced in ECMAScript 6 (ES6). They are called arrow functions because they use a special syntax with an arrow ( => ) to define the function.

For comparison, a traditional function might look like this:
function sum(a, b) {
  return a + b;
}

Its equivalent as an arrow function is:
const sum = (a, b) => a + b;

The main benefit of an arrow function is that it doesn't create its own execution context (binding to this), which is often a source of errors in JavaScript. In arrow functions, this is inherited from the surrounding context. Another advantage is the brevity of syntax, especially useful when functions are used as arguments to other functions, e.g. in higher-order functions.

On the other hand, due to the lack of its own this, arrow functions are not suitable for defining constructor (creative) objects or for creating methods in prototype objects.

What is a Promise object and how can it be used?

The Promise object in JavaScript is used to handle asynchronous operations. A Promise represents a value that may not be available at the time the Promise is created, but may be available in the future, or never at all.

A Promise object can be in one of three states:
1. Pending - operation is still ongoing, not finished either successfully or with errors.
2. Fulfilled - operation completed successfully, Promise returned a value.
3. Rejected - operation completed with an error, Promise returned the reason for the error.

A Promise that has been fulfilled or rejected is considered "settled" and its state never changes.

Creating a Promise object:
const promise = new Promise((resolve, reject) => {
  const success = true;
  if (success) {
    resolve('Operation successful.');
  } else {
    reject('Operation failed.');
  }
});

Using a Promise object:
promise
  .then(result => {
    console.log(result); // Will print: 'Operation successful.'
  })
  .catch(error => {
    console.log(error);
  });

The .then() method is executed when the Promise is fulfilled, and .catch() when it is rejected. In both cases, the result of the operation or the reason for the rejection of the Promise is passed as an argument.

What is a callback?

A callback, also referred to as a callback function, is a function that is passed as an argument to another function and is then executed (called back) after the completion of that function. Callback functions are commonly used in JavaScript, particularly in asynchronous operations such as AJAX requests or event handling.

Callback functions usually receive the results of a certain operation as arguments, so they can be used for processing or analyzing those results.

The usage of such a function in practice may look as follows:
function executeAfterTimeout(callback, timeout) {
  setTimeout(() => {
    console.log('Time passed!');
    callback();
  }, timeout);
}

executeAfterTimeout(() => {
  console.log('This is a callback!');
}, 2000);

In this case, the function `executeAfterTimeout` receives a `callback` function as a parameter, which will be executed after a specified amount of time has passed. Callback functions are extremely useful for managing asynchronous control flow in JavaScript.

What is the nullish coalescing operator and how does it work?

The Nullish Coalescing Operator (??) is a logical operator that returns the right-hand side of the operation when the left-hand side is null or undefined. In other words, when a variable is empty, the nullish coalescing operator returns the defined value as a result.

The basic notation is:
let value = null ?? 'default value';

In this case, as the left-hand side (value) is null, the result is 'default value'. Additionally, this operator differs from the OR operator (||), as the OR function returns the right-hand side when the left-hand side is false (false, 0, '', null, undefined, NaN), while the nullish coalescing operator only returns the right-hand side when the left-hand side is null or undefined.

Example with OR:
let value1 = 0 || 'default';
console.log(value1); // output: 'default' because 0 is a false value

Example with nullish coalescing:
let value2 = 0 ?? 'default';
console.log(value2); // output: 0 because 0 is not null or undefined

So, unlike OR, the nullish coalescing operator does not treat 0, '' and NaN as "empty" values.

What is Symbol and when should it be used?

A Symbol in JavaScript is a unique and immutable data type that is often used to identify unique properties of objects.

You can create a Symbol by calling the Symbol() constructor, which creates a unique symbol each time it is called. Even if we call the Symbol() constructor with the same argument, each created symbol will be different.
const symbol1 = Symbol('mySymbol');
const symbol2 = Symbol('mySymbol');
console.log(symbol1 === symbol2); // returns false

Symbol is often used to define (unique) properties of objects, especially when we want this property to be hidden or private. It also covers properties that are not considered when iterating over objects using for...in or for...of and are not returned by the Object.keys() method. Moreover, symbols allow creating "pseudo" private properties.
let obj = {};
let privateProperty = Symbol('private');

obj[privateProperty] = 'This is private';

console.log(obj[privateProperty]); // 'This is private'
console.log(Object.keys(obj)); // []

There is no definite rule on when to use Symbol. They are typically used when we want to create a unique property on an object that cannot be easily seen or changed, or we want to define methods that affect the behavior of objects at a low level.

What are WeakMap and WeakSet?

WeakMap and WeakSet are special versions of JavaScript Map and Set objects that do not prevent automatic memory release by the Garbage Collector.

WeakMap is a collection of key-value pairs where keys must be objects and values can be anything. The main difference between Map and WeakMap is that keys in WeakMap are held "weakly", meaning that if there are no other references to the key object, it will be garbage-collected, and its entry in WeakMap will be automatically removed.

Here is an example of using WeakMap:
let john = { name: "John" };

let weakMap = new WeakMap();
weakMap.set(john, "...");

john = null; // overwrite the reference

// john is removed from memory!

WeakSet is similar to what WeakMap is to Map. It's a set of objects, but it doesn't prevent garbage-collection if the object is not visible anywhere else. It lacks typical Set methods like `size` and `clear`, and `add` method only takes objects.

Example of using WeakSet:
let john = { name: "John" };

let weakSet = new WeakSet();
weakSet.add(john);

john = null; // overwrite the reference

// john is removed from memory!

Both, WeakMap and WeakSet, are mainly used in situations when we want to store additional information about objects that should be removed when the object itself is removed.

Download IT Flashcards App Now

Expand your JavaScript knowledge with our flashcards.
From basic programming principles to mastering advanced technologies, IT Flashcards is your passport to IT excellence.
Download now and unlock your potential in today's competitive tech landscape.