Javascript Interview Questions

Javascript Interview Questions

by John Vincent


Posted on February 23, 2017



Let’s describe some of the potential interview questions.

My references

There are many excellent references. Let’s list a few:

37 Questions

10 Questions

51 Questions

100 Questions

85 Questions

Let vs Var

  • var is hoisted, let is not
  • var is function scope, let is block scope
  • let is es2015, will not work on older browsers

== vs ===

Comparison operators.

== compares the value

=== compares the value and the type.

let vs const

const, cannot reassign, can modify if an object.

let, can change

undefined vs null

They both represent an empty value.

When define a variable but do not assign a value, the variable is undefined

null is expressly set.

typeof(undefined) => undefined

typeof(null) => object

Use of arrow function

Example

const profile = {
  first: '',
  laat: '',
  setName: function(name) {
    let splitName = function(n) {
      let nameArray = n.split(' ');
      this.first = nameArray[0];	// same as window.first
      this.last = nameArray[1];
    }
    splitName(name);
  }
}

profile.setName('bill blunt');
console.log('first ', first); => 'bill'

Arrow function does not have it’s own this

const profile = {
  first: '',
  laat: '',
  setName: function(name) {
    let splitName = (n) => {    // 'this' refers to 'setName', which is profile object
      let nameArray = n.split(' ');
      this.first = nameArray[0];
      this.last = nameArray[1];
    }
    splitName(name);
  }
}

profile.setName('bill blunt');
console.log('first ', profile.first);

Example

var x = function() {
  this.val = 1;
  setTimeout(function() {
    this.val++;
    console.log(this.val);		// NaN
  }, 1);
};

var xx = new x();

as this refers to the function in setTimeout

Use that

var x = function() {
  var that = this;
  this.val = 1;
  setTimeout(function() {
    that.val++;
    console.log(that.val);
  }, 1);
};

var xx = new x();

or, using Arrow functions

var x = function() {
  this.val = 1;
  setTimeout(() => {
    this.val++;
    console.log(this.val);
  }, 1);
};

var xx = new x();
var x = function() {
  console.log(arguments[0]);
};
x(1,2,3);		// 1

var x = () => {
  console.log(arguments[0]);
};
x(1,2,3);		// {}

var x = (...n) => {
  console.log(n[0]);
};
x(1,2,3);		// 1

Prototypal Inheritance

Every object has a property called prototype.

The Object.prototype is on the top of the prototype inheritance chain. All objects inherit from Object.prototype.

The prototype property allows addition of new properties and methods to object constructors.

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}

Person.prototype.nationality = "English";

Person.prototype.name = function() {
  return this.firstName + " " + this.lastName;
};

Class Inheritance vs Prototypal Inheritance?

Class Inheritance

A class is like a blueprint — a description of the object to be created. Classes inherit from classes and create subclass relationships: hierarchical class taxonomies.

Instances are typically instantiated via constructor functions with the new keyword.

Prototypal Inheritance

A prototype is a working object instance. Objects inherit directly from other objects.

Instances are typically instantiated via factory functions, object literals, or Object.create()

function declaration vs function expression

console.log(funcD());
console.log(funcE());		// not defined

function funcD() {			// cannot pass to another function
	console.log('function declaration');
}

let funcE = function() {	// can pass to another function
	console.log('function expression');
}

What are Promises

Use a Promise if need to make an async call that has to wait for the response to continue.

A promise is an object which can be returned synchronously from an asynchronous function. It will be in one of 3 possible states:

  • Fulfilled: onFulfilled() will be called (e.g., resolve() was called)
  • Rejected: onRejected() will be called (e.g., reject() was called)
  • Pending: not yet fulfilled or rejected

Example

const wait = time => new Promise((resolve) => setTimeout(resolve, time));

wait(3000).then(() => console.log('Hello!')); // 'Hello!'
  • Promise.reject() returns a rejected promise.
  • Promise.resolve() returns a resolved promise.
  • Promise.race() takes an array (or any iterable) and returns a promise that resolves with the value of the first resolved promise in the iterable, or rejects with the reason of the first promise that rejects.
  • Promise.all() takes an array (or any iterable) and returns a promise that resolves when all of the promises in the iterable argument have resolved, or rejects with the reason of the first passed promise that rejects.

Promise Chaining

.then() always returns a new promise, thus can chain.

fetch(url)
  .then(process)
  .then(save)
  .catch(handleErrors)
;

setTimeout()

setTimeout(function() {
  console.log('a');
}, 0);
console.log('b');
console.log('c');

b
c
a

as b and c are on the stack and will be excuted first, then the asynchronous will get ot the event loop and be executed.

What is a closure and how to you use it

When a function returns another function, the returning function will have access to the variables in the outer function scope.

let obj = function() {
  let i = 0;			// environment

  return {
    setI(k) {
      i = k;
    },
    getI() {
      return i;
    }
  }
}

let x = obj();
x.setI(2);
console.log(x.getI());		// 2

Closures are frequently used in JavaScript for

  • object data privacy
  • event handlers and callback functions, and in partial applications, currying, and other functional programming patterns.

Function Composition

Function composition is the process of combining two or more functions to produce a new function. Composing functions together is like snapping together a series of pipes for our data to flow through.

const toSlug = input => encodeURIComponent(
  input.split(' ')
    .map(str => str.toLowerCase())
    .join('-')
);

Functional Programming

Functional programming is a programming paradigm, a style of building the structure and elements of computer programs, that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.

Functional programming is the process of building software by composing pure functions, avoiding shared state, mutable data, and side-effects.

Functional programming is declarative rather than imperative, and application state flows through pure functions. Contrast with object oriented programming, where application state is usually shared and colocated with methods in objects.

idempotent

The output value of a function depends only on the arguments that are passed to the function, so calling a function f twice with the same value for an argument x produces the same result f(x) each time.

Pure Function

A pure function is a function that has the following properties:

Given the same inputs:

  • always returns the same output, and
  • has no side-effects

Higher Order Function

A higher order function is any function which takes a function as an argument, returns a function, or both. Higher order functions are often used to:

  • Abstract or isolate actions, effects, or async flow control using callback functions, promises, monads, etc…
  • Create utilities which can act on a wide variety of data types
  • Partially apply a function to its arguments or create a curried function for the purpose of reuse or function composition
  • Take a list of functions and return some composition of those input functions

Declarative vs Imperative

Functional programming is a declarative paradigm, meaning that the program logic is expressed without explicitly describing the flow control.

Imperative programs spend lines of code describing the specific steps used to achieve the desired results — the flow control: How to do things.

Imperative example

const doubleMap = numbers => {
  const doubled = [];
  for (let i = 0; i < numbers.length; i++) {
    doubled.push(numbers[i] * 2);
  }
  return doubled;
};

console.log(doubleMap([2, 3, 4])); // [4, 6, 8]

Declarative programs abstract the flow control process, and instead spend lines of code describing the data flow: What to do. The how gets abstracted away.

Declarative example

const doubleMap = numbers => numbers.map(n => n * 2);

console.log(doubleMap([2, 3, 4])); // [4, 6, 8]

Other

console.log(2 + '2');		// 22
console.log(2 - '2');		// 0
console.log(5 < 6 < 7);		// true
console.log(7 > 6 > 5);		// false

as

console.log(true < 7);		// 1 < 7 => true
console.log(true > 5);		// 1 not greater than 5 => false
let a = () => arguments;	// arguments do not bind to the arrow function
console.log(a('hi'));		// arguments is not defined

let a = function(arguments) {
  return arguments;
}
console.log(a('hi'));		// hi

let a = (...n) => n;
console.log(a('hi'));		// ['hi']

Make an array of unique numbers

let nums = [1, 2, 2, 3];
const jv = new Set(nums);   // returns a set of unique numbers
console.log([...jv]);	// array

Object.freeze() vs Object.seal()

.freeze() prevents any changes to the object.

let profile = {
  name: 'bill'
};
profile.age = 3;
console.log(profile);		// { name: 'bill', age: 3 }
let profile = {
  name: 'bill'
};
Object.freeze(profile);
profile.name = 'fred';
profile.age = 3;
console.log(profile);		// { name: 'bill' }

.seal() allows changes to already existing properties and prevents addition of new properties.

let profile = {
  name: 'bill'
};
Object.seal(profile);
profile.name = 'fred';
profile.age = 3;
console.log(profile);		// { name: 'bill' }

Object.defineProperty()

Add properties to an object.

var profile = {
  name: 'bill'
};
Object.defineProperty(profile, 'age', {
  value:3,
  writable: false,
  enumerable: true,
});

profile.name = 'fred';	// changed
profile.age = 4;		// not changed
console.log(profile);	// { name: 'fred', age: 3 }

Math.max()

console.log(Math.max());		// -Infinity

Array myReduce()

Array.prototype.myReduce = function(fn, init) {
  let sum = init;
  this.forEach(item => {
    sum = fn(item, sum);
  });
  return sum;
}

const total = [1,2,3].myReduce((c,v) => c + v, 0);
console.log('total ', total);		// 6

Create Promise

let myPromise = function(fn) {
  return new Promise(function(resolve, reject) {
    if (fn)
      resolve('good');
    else
      reject('error');
  });
}

function fn() {
  console.log('fn');
}

myPromise(fn)
.then(value => { 
  console.log('(1) value ', value);
})
.catch(err => { 
  console.log('(1) err ', err);
});

myPromise(null)
.then(value => { 
  console.log('(2) value ', value);
})
.catch(err => { 
  console.log('(2) err ', err);
});

f(1)(2)(3)

function f(a, b, c) {
  if (! a) return 0;
  if (a && b && c) return (a + b) * c;

  return function(b) {
    return function(c) {
      return (a + b) * c;
    }
  }
}

console.log('f() ', f());			// 0
console.log('f(null) ', f(null));		// 0

console.log('f(3, 2, 4) ', f(3, 2, 4));	// 20
console.log('f(1)(2)(3) ', f(1)(2)(3));	// 9
console.log('f(2)(2)(1) ', f(2)(2)(1));	// 4

Add to start of Array

var myArray = ['a', 'b', 'c', 'd'];
myArray.unshift('1','2');
console.log(myArray);	// ["1", "2", "a", "b", "c", "d"]

Add to end of Array

var myArray = ['a', 'b', 'c', 'd'];
myArray.push('e', 'f');
console.log(myArray);	// ["a", "b", "c", "d", "e", "f"]

How to create a private variable

function secretVariable() {
  let secret = 'a secret';
  return function() {
    return secret;
  }
}

let obj = secretVariable();
console.log(obj);		// the function

console.log(obj());		// 'a secret'
function outer(param) {
  let body = param;
  return {
    getBody() {
      return body;
    }
  }
}

let x = outer('some value');
console.log(x.getBody());	// some value

console.log('test 1 ', x.body);	// undefined

What is the output

var num = 4;
function outer() {
  var num = 2;
  function inner() {
    num++;
    var num = 3;
    console.log(num);		// 3
  }
  inner();
}
outer();

What is the output

console.log(typeof typeof 1);		// string

as

console.log(typeof 1);		// 'number'

What is the output

var hero = {
  _name: 'bill',
  getName: function() {
    return this._name;
  }
};
var name = hero.getName;

console.log('name() ', name());		// undefined
console.log('hero.getName() ', hero.getName());	// 'bill'

var test = hero.getName.bind(hero);
console.log('test() ', test());		// 'bill'