9 JS Interview Questions

Published: 2019-06-12

These nine questions come from an article on Medium"9 JavaScript Interview Questions". The author divides them into two parts: the first examines some JavaScript quirks, which the author calls Curveball Questions; the second part covers general questions, Common Questions.

CURVEBALL QUESTIONS

1. WhyMath.max()is less thanMath.min()?

In JS,Math.max() > Math.min()returnsfalse, which seems counterintuitive, but if you analyze it carefully, you will findfalsethis result is logically sound.

When called without any arguments,Math.min()andMath.max()return respectivelyinfinityand-infinity. Why do they return these values? Let's look at some code:

Math.min(1) 
// 1
Math.min(1, infinity)
// 1
Math.min(1, -infinity)
// -infinity

If-infinityis the default argument forMath.min()then all results would be-infinity, and the function would be useless! But ifinfinityis its default argument, then the function returns the smallest of the inputs, which is the expected behavior.

2. Why does0.1 + 0.2 === 0.3returnfalse?

In short, this relates to how JS represents floating-point numbers precisely in binary. If you enter the code below in Chrome's console, you'll see:

0.1 + 0.2
// 0.30000000000000004
0.1 + 0.2 - 0.2
// 0.10000000000000003
0.1 + 0.7
// 0.7999999999999999

If you don't require high-precision calculations and only perform simple arithmetic, this is usually fine. But this issue can still be frustrating in some simple equality comparisons. Here are some solutions.

Fix decimal places.If you know the maximum precision you need exactly—such as for currency—you can store the value as an integer. For example¥4.99can be converted to 499 for storage and calculation; finally, at the user display layer handle it with an expression likeresult = (value / 100).toFixed(2), which returns a string.

Number​.prototype.toFixed([digits])

This method accepts a parameter from 0 to 20 indicating the number of digits after the decimal point; if omitted, the default is 0. Note that it willround the last digit.

Number(0.1+0.7).toFixed(1) // '0.8'

3. Why does 018 minus 017 equal 3?

018 - 017It returns 3; this issue relates to implicit type conversion. Let's first discuss octal.

In computing, binary and hexadecimal are commonly used, but historically octal played an important role in the 1950s and 1960s: it was used as a concise way to represent binary and reduce costs. Later, hexadecimal quickly emerged and was adopted. SeeQuora.

What role does octal play in modern computing? In some scenarios octal has advantages over hexadecimal because it doesn't require letters for counting (no A–F). A common application is Unix file permission representation: there are eight permission modes:

   4 2 1
0  - - - no permissions
1  - - x only execute
2  - x - only write
3  - x x write and execute
4  x - - only read
5  x - x read and execute
6  x x - read and write
7  x x x read, write and execute

For similar reasons, it is also used in numeric displays.

Back to the question: in JS, any number prefixed with0is treated as an octal literal. However,8this digit does not exist in octal, so a number containing8will be implicitly converted to a regular decimal number. Thus017is octal,018is decimal, so expressing018 - 017in decimal is equivalent to18 - 15.

COMMON QUESTIONS

4. What is the difference between function expressions and function declarations?

A function declaration begins with thefunctionkeyword followed by the function name. A function expression begins withvar,letorconstfollowed by the function name and an assignment operator=. Here are some examples:

// Function Declaration
function sum(x, y) {
  return x + y;
};

// Function Expression: ES5
var sum = function(x, y) {
  return x + y;
};

// Function Expression: ES6+
const sum = (x, y) => { return x + y };

In usage,their most important difference is that function declarations are hoisted, while function expressions are not. Function declarations are hoisted to the top of their scope by the JS interpreter, so you can call them anywhere. By contrast, you can only call function expressions in sequence—that is, you must define a function expression before calling it.

Today many developers prefer function expressions, and there are several reasons:

  • The primary reason is that function expressions make it easier to write more predictable, structured code. Of course, function declarations can also support structured code.

  • Second, we can use ES6 syntax to define function expressions, which is often more concise, and using let and const helps us better control whether a variable can be reassigned. You will see this more clearly in the next question.

5. What is the difference between var, let and const?

Since ES6 was released, this question has become a common interview topic. From the first versions of JS,varwas used as the variable declaration keyword, but its shortcomings prompted ES6 to introduce two new keywords to replace it:letandconst.

These three keywords differ in their handling ofassignment, hoisting and scope. Let's look at each.

Assignment.The most basic difference is thatletandvarcan be reassigned, whereasconstcannot. If a variable does not need to change, it is best to declare it as const to avoid accidental reassignment. Note thatconstallows mutation of the variable (constant), which means if the variable (constant) references a compound data type like an array or object, you can change the values stored in that reference, but you cannot change the reference itself.letandvarBoth can be reassigned, but you should understand thatletis preferable tovar.

you don't use declaration keywords like

,xorvar, andlet, andconsthas not been defined, thenxis equivalent tothe variable "window.x = 1. The original author discussedmemory management issues in JSand noted thatsuch usage can cause memory leaksTo prevent such mistakes, you can use strict mode introduced in ES5 by adding at the top of a document or function the line.

"use strict". In that mode, if you assign without a declaration keyword you will get an error:Uncaught SyntaxError: Unexpected indentifier7. What is the difference between Object-Oriented Programming (OOP) and Functional Programming (FP)?.

JS is a multi-paradigm language, meaning it supports many programming styles, including event-driven, functional, and object-oriented.

There are many programming paradigms in computer science, but functional programming and object-oriented programming are currently among the most popular, and JS supports both styles.

Object-Oriented Programming (

Object-Oriented ProgrammingOOP is based on the concept of "objects." An object is composed of a set of properties and methods.)

JS has some built-in objects, such as

MathJSON, andand some primitive types likeStringArray,Number,BooleanandIn practice you'll use methods from built-in objects or prototypes and classes; essentially, this is practicing object-oriented programming..

Functional Programming (

Functional ProgrammingFP is based on the concept of ")

pure functions". It advocates avoiding shared state, mutable data and side effects. These sound like many constraints, but you have plenty of opportunities to write pure functions in your code.Given the same input, a pure function always produces the same output. Pure functions must not have side effects, such as logging to the console or modifying external variables; these go beyond the function's return value.

Regarding shared state, the following example shows how changing context alters the function output for the same input. We wrote two functions: one adds 5, the other multiplies by 5.

const num = {

val: 1
  const add5 = () => num.val += 5;
}; 
const multiply5 = () => num.val *= 5; 
If we call

add5first and thenmultiply5, the result is 30. But if we call them in the opposite order, we get 10.This violates functional programming principles because the functions mutate shared context. Below we rewrite the example to make results predictable:

const add5 = () => Object.assign({}, num, {val: num.val + 5});

val: 1
  const add5 = () => num.val += 5;
};
const multiply5 = () => Object.assign({}, num, {val: num.val * 5}); 
Now

num.valis no longer changed, and regardless of context,add5()multiply()andwill always return consistent results.8. What is the difference between imperative and declarative programming?

When discussing the difference between

declarative programmingandandimperative programming, we can similarly reflect on the difference between OOP and FP.

These are general labels for common characteristics across different paradigms. Functional programming is a typical example of declarative style, while object-oriented programming exemplifies imperative style.

Basically,imperative programming cares about how you do something. It spells out each key step with for or while loops, if or switch statements everywhere.

const sumArray = array => {
  let result = 0;
  for (let i = 0; i < array.length; i++) { 
    result += array[i]
  }; 
  return result;
}

By contrast,declarative programming cares about what you want to do, abstracting the logic from the how. This style leads to more concise code, but in large-scale applications its lower transparency can make debugging harder.

Here is a declarative rewrite of thesumArray()function above:

const sumArray = array => { return array.reduce((x, y) => x + y) };

9. What is prototype-based inheritance?

JS implements object-oriented inheritance through the prototype system. In fact, built-in array methods likemap, andreduce, andspliceetc., are inherited fromArray.prototype. Likewise, objects such asArray, andIn practice you'll use methods from built-in objects or prototypes and classes; essentially, this is practicing object-oriented programming.also have prototypes, but values likeInfinity,NaN,nullandexecuting the codedo not have properties or methods.

Should you override or extend behavior on prototypes?

Almost every object in JS ultimately inherits fromObject.prototype. You can easily add properties and methods to an object using theprototypekeyword or alter built-in object behavior, but most companies discourage doing so.

function Person() {};
Person.prototype.forename = "John";
Person.prototype.surname = "Smith";

If you want several objects to share behavior, create a base or derived class that inherits from built-in prototypes rather than changing the built-in objects themselves. When collaborating with others, expectations about JS default behavior should be consistent, and modifying those defaults can easily introduce bugs.

However, it is worth noting that not everyone agrees that extending built-in prototypes should be forbidden.In this article, Eich argues that part of the reason prototypes were designed was to support extension.

Last updated