50 Difficult JavaScript Questions to Test Your JS Knowledge

I meticulously searched the JavaScript docs to create these questions. I hope they push the limits of your JS knowledge. Let me know in the comments if you enjoyed this list!

Related: Test your TypeScript knowledge against these 50 difficult TypeScript questions.


1. What will the code below output to the console and why?

const person = {
  age: 20,
  name: 'Ben'
};

const peopleArray = [person, person, person];
peopleArray[1].name = 'Joe';
console.log(peopleArray[0].name);

It will print Joe. The peopleArray has three elements, but all three elements are references to the same memory space, which is the person object. The following will create an array with three unique objects and outputs Ben.

const person = {
  age: 20,
  name: 'Ben'
};

const peopleArray = [{...person}, {...person}, {...person}];
peopleArray[1].name = 'Joe';
console.log(peopleArray[0].name);

2. What will the code below output to the console and why?

const carOne = {
  color: 'blue',
  status: {
    running: true,
    passengers: 4,
    wiperFluid: 'empty'
  },
  age: 5,
  miles: 50000,
  value: '8000'
}

const carTwo = {
  color: 'green',
  status: {
    running: 'yes',
    passengers: 2,
    fuelTank: 'empty'
  },
  value: 9000
}

const combinedCar = {
...carOne,
...carTwo
}

console.log(combinedCar);

It will print the following the below output. Any property names common to both destructured objects will be overwritten by the second object.

{
  age: 5,
  color: "green",
  miles: 50000,
  status: {
    fuelTank: "empty",
    passengers: 2,
    running: "yes"
  },
  value: 9000
}

3. Will the following code compile? If not, why not?

const myName = 'Jim'; // Line 1

if(myName){ // Line 2
  myName = 'Joe'; // Line 3
  let myName = 'Jeff'; // Line 4
}

The code does not compile. Interestingly, Line 3 fails because let myName is not initialized to undefined (unlike var myName would have been). If Line 4 were removed, then Line 3 would fail due to the inability to override myName declared as a constant outside the code block. Constants cannot be changed.

4. What will the code below output to the console and why?

const myMoney = {
  quarters: 4,
  dimes: 10,
  nickels: 20,
  pennies: 100
}

for (const coin of myMoney){
  console.log(`${coin}: ${myMoney[coin]}`);
}

The code will actually throw an error. for…of can only be used on objects that implement the @@iterator method. See this great article that covers four different ways to loop in JavaScript for more information. for…in would have printed off each key:value pair.

5. Write an arrow function that successfully prints “hello world” given the following function call:

console.log(concatenator('hello')('world'));

Here is one way to accomplish this:

const concatenator = (originalStr) => {
  return (strTwo) => { return `${originalStr} ${strTwo}`; };
}

The questions continue below, but first I recommend you check out my book, 300 JavaScript Interview Mastery Questions(affiliate link).The questions explore a wide variety of JavaScript syntax, functions, APIs, and theory. You WILL learn something new in this book and be better prepared for your next interview.


6. What will the code below output to the console and why?

const myArr = [1,2,3];
const arrTwo = myArr.splice(0,4).slice(0,2);
arrTwo[0] = 9;
console.log(arrTwo);

The code will output [9, 2]. Array.splice returns the original array, but Array.slice returns a new array, so changing arrTwo does not affect myArr.

7. What will the code below output to the console and why?

const person1 = {
  name: 'Willie',
  address: {
    city: 'Austin',
    state: 'Texas'
  }
};

const person2 = {...person1};

person2.name = 'Waylon';
person2.address.city = 'Fort Worth';

console.log(person1.address.city);

The output will be ‘Fort Worth’. Creating a new object using … is the equivalent of using Object.assign({}, object); and creates a shallow copy. person1 and person2 are not the same object, but both person1.address and person2.address are pointed to the same object in memory. See this article for a deeper explanation of shallow and deep copies in JavaScript.

7. What is the difference in the ‘~’ and the ‘^’ in the semver syntax, such as that used in npm package.json file?

Semver syntax goes as follows: major.minor.patch. The ‘~’, such as “lodash”: “~1.2.0”, will only update the patch version. The ‘^’, such as “lodash”: “^1.2.0”, will update the minor and patch version.

8. Name a JavaScript String function that modifies the original string.

Admittedly, this is a trick question. Strings are immutable in JavaScript, so there are no functions that modify the original string. There are some functions that extract or change portions of the original string and return it as a new string, leaving the original string unmodified.

9. True or False? In the code below, myColor is initialized with a boolean value of true.

const myColor = 'Purple' || 'Red';

This is false. The || operator does not actually return a boolean value, but rather the first truthy value it encounters. ‘Purple’ is a truthy value, so myColor is initialized to ‘Purple’.

10. Optimize the following code:

function truthy(x) {
  if(5 === x){
    return true;
  }else {
    return false;
  }
}

console.log(truthy(6));

Here is a simple optimization:

function truthy(x) {
  return 5 === x;
}

console.log(truthy(5));

Many devs write redundant lines of code, forgetting that ‘===’ itself returns a boolean.

11. Given the below example, what is the result of setting enumerable: false in Object obj?

const obj = {};

Object.defineProperty(obj, 'key1', {
  enumerable: false,
  configurable: true,
  writable: true
});

Object obj will not be enumerated over in a for…in loop.

12. What will the code below output to the console and why?

const obj1 = {a: 1, b: 2};
const obj2 = {b: 1, c: 2};
const obj3 = {c: 1, d: 2};

Object.assign(obj1, obj2, obj3);
console.log(obj1);

The code will output {a: 1, b: 1, c: 1, d: 2}. Object.assign can take multiple sources, and later sources overwrite earlier sources.

13. What will the code below output to the console and why?

const obj1 = {
  prop1: 'testA',
  prop2: (() => {
    return obj1.prop1;
  })()
}

console.log(obj1.prop2);

It will throw an error saying ‘cannot access obj1 before initialization’. The code is attempting to immediately invoke the arrow function at prop2 while obj1 is still being initialized.

14. Consider the code below. How can object properties be accessed using a variable?

const key = 'prop1';

const obj1 = {
 prop1: 1,
 prop2: 2
}

// console.log(???)

console.log(obj1[key]); will access prop1 on obj1. This is useful in many situations, such as when enumerating using a for…in loop.

15. What are some limitations placed by using Strict Mode in JavaScript?

Take a look here for an exhaustive list. Most of the limitations revolve around variables. For example:

  • all variables must be declared (the compiler won’t assume an undeclared variable is a global
  • reserved words cannot be used as variable names
  • certain preceding values are not allowed, such as let badVal = /010;
  • deleting undeletable properties is not allowed

16. Consider the code below. Do arr4 and arrControl have the same values?

const arr1 = 'jimmy'.split('');
const arr2 = arr1.reverse();
const arr3 = arr2.splice(0,5);
const arr4 = arr3.slice(0,5);


const arrControl = 'jimmy'.split('').reverse().splice(0,5).slice(0,5);

They do indeed have the same values: [“y”, “m”, “m”, “i”, “j”]. It doesn’t matter whether the individual function returns are assigned to a const and then used, the result is the same either way.

17. Consider the code below. Do Line 8 and Line 9 log the same value to the console?

const memoryFunction = (x) => {
  const y = x;
  return (z) => {
    console.log(y * z);
  }
}

const innerMemoryFunction = memoryFunction(5);

memoryFunction(6)(6); // Line 8
innerMemoryFunction(6)(6); // Line 9

Line 8 logs a value of 36. Line 9 initially logs a value of 30 and then throws an error. innerMemoryFunction is assigned a value of (z) => { console.log(y*z); }. This function has captured the closure value of y = 5 and uses that value when calculating.

18. What will the code below output to the console and why?

console.log(1 && 0 === 1 || 0);

At first glance you may try to evaluate whether 1 && 0 is equivalent to 1 || 0. However, that’s not what the above code is doing. The code above is actually equivalent to the below:

console.log(1 && (0 === 1) || 0);

Which is the same as:

console.log((1 && false) || 0);

The || operator returns the second value it checks when the first value is false, and since 1 && false is falsy, the above returns 0.

19. What are two ways to push elements of one array into another array using only one line of code?

Here are two possible ways to do it.

Option 1:

const arr1 = [3,4,5];

[1,2, ...arr1];

This is simply just destructuring assignment.

Option 2:

const arr = [1, 2];
arr.push.apply(arr, [3, 4, 5]);

This option is a little more complex. arr.push on line 2 simply calls the push function. The first param (arr) in the apply function actually tells the compiler which array to call the push on.

19. Consider the code below. Why doesn’t toString throw an error even though we have not defined it on Car?

function Car (wheels){
  this.wheels = wheels;
}

const myCar = new Car(4);

myCar.toString()

toString is an instance method of Object. Car is of type Object, so it has all methods that Object has.

20. Consider the code below. Why does Line 1 return true while Line 2 returns false?

console.log(null == undefined == 0 == ''); // Line 1
console.log(null == undefined == 0 == '' == NaN); // Line 2

These evaluate as follows for Line 1:

  • null == undefined // true
  • true == 0 // false
  • false == ” //true

So Line 1 returns true

Line 2 then evaluates true == NaN which is false.

21. Can functions be passed as parameters?

Yes, and here is an example:

const Person = (firstName, lastName, getUniqueID) => {
  return {
    firstName: firstName,
    lastName: lastName,
    getUniqueID: getUniqueID
  }
}

const person1 = Person(
  'Jon',
  'Jones',
  () => {
    return (person1.firstName + person1.lastName + Math.floor(Math.random() * 100))
});

This is an example where TypeScript would provide value. A developer looking at the Person constructor might guess that getUniqueID should be a function, but if the parameter had a type it would significantly reduce opportunity for confusion and bugs.

22. Why should developers use ‘===’ instead of ‘==’?

‘===’ is stricter and checks if value and type are the same, ‘==’ only checks value and will do type coercion. But WHY do we want it stricter? Because developers need to write code that works as intended. Higher standards on code is a good thing and ensures developers don’t get sloppy.

23. True or False? A catch block is required after a try{}.

This is false. However, either a catch block or a finally block is required after a try{}.

24. Why does console.log(~8) output -9?

~ is a bitwise operator that flips bits in the bit representation of a number. In JavaScript all bitwise operations are performed on 32-bit binary numbers.

8 is represented as 00000000000000000000000000001000. The ~ operator flips this to 11111111111111111111111111110111, which is -9

25. What will the code below output to the console and why?

for(let i = 0; i < 10; i++){
  if(i === 3){
   return;
  }
  console.log(i);
}

This will throw a syntax error. The return statement is not a valid way of ending a for block. If you want to end a loop, use break.

26. What are two methods for extracting the keys from an Object?

There are a handful of ways this could be accomplished, but two are below.

Option 1:

const obj1 = {
  a: 'this',
  b: 'that',
  c: 'the other'
}

console.log(Object.keys(obj1));

Object.keys(obj1) will extract the keys and return an array populated with a string representation of the keys.

Option 2:

const obj1 = {
  a: 'this',
  b: 'that',
  c: 'the other'
}

for(const key in obj1){
  console.log(key);
}

Using for…in, each key is iterated over and a string representation of its value is set to the constant ‘key’ in the above example.

27. What will the code below output to the console and why?

let date = new Date(95, 3);
console.log(date.toLocaleString('default'));

It prints “4/1/1995, 12:00:00 AM”. When only a year is provided, it maps to the 20th century. Also, January is month 0. Therefore, new Date(95, 3) creates a Date object set to April 1995.

28. What will the code below output to the console and why?

console.log(typeof (new String('hello')));

It will print ‘object’. We have created a string Object, which is different than a string primitive in JavaScript.

29. What will the code below output to the console and why?

let x = 10;
setTimeout(() => {console.log(x);}, 1000);
x = 5;

The output is 5. The timeout callback is not evaluated until 1000 milliseconds have passed, so x is never set to 10. It is only set once, to 5, and that is when the callback is evaluated.

30. Will the below code execute?

() => {console.log("problem?");}();

It will not. When attempting to immediately invoke an arrow function, don’t forget the needed parenthesis, like below:

(() => {console.log("problem?");})();

31. What will the code below output to the console and why?

console.log(typeof Object)

The output is “function”. While this may seem strange at first, Object is the name of the Object constructor function.

32. Will the following code run?

let hoister = 10;
const isItHoisted = function () {
    console.log(hoister);
    let hoister = 9;
};
isItHoisted();

The code will not run, but instead has a compile time error. let does not get hoisted, but the compiler doesn’t try to use the hoister variable specified outside the function.

33. What does the accumulator do in Array.prototype.reduce()?

The return value of the each iteration of the reducer function is assigned to the accumulator and remembered across each iteration of the array.

34. A user is typing into a textbox, and the onChange is being fired more often than desired. What function could be used to only fire the onChange at the end of the user’s typing?

debounce. The debounce function forces a function to wait a certain amount of time before being called or before being called again. Scroll events are another common use for debounce.

35. What function tells the browser to call a specified function to update an animation before the next repaint?

window.requestAnimationFrame(). This is a useful function for making animations render more smoothly and more often.

36. If a button exists inside a div, and both the button and div have click listeners, which one handles the event first? Do they both handle the event?

The button click handler will be invoked, then the div click handler will be invoked. If you do not wish for the div to also have it’s click handler invoked, add event.stopPropagation() in the button click handler.

37. What will the code below output to the console and why?

console.log(isNaN(false));

This will output false. The value false will be coerced to 0, and NaN(0) will return false.

38. Given that console.log(new Number(5)); logs the value 5, what will the code below output to the console and why?

console.log(new Number(5) === 5);

This logs the value false. new Number(5) is an object, when it is logged to the console it’s toString() method is called so the value 5 is logged.

39. Write a function that determines if a character is an upper case letter.

One possible solution:

function isUpper(character){
  const asciiVal = character.charCodeAt(0);
  return asciiVal >= 65 && asciiVal <= 90;
}

40. What convenience method was added with ES6 to arrays to create an array from array-like and iterable objects?

Array.from. Consider the following example:

const items = Array.from(document.querySelectorAll('li'));

41. What will the code below output to the console and why?

console.log(
  ['Monday', 'Tuesday', 'Wednesday','Thursday', 'April', 'May', 'daylight'].filter(element => element.slice(-3) !== 'day')
);

This will output [“April”, “May”, “daylight”]. Adding parenthesis around the element param is not required because it is the only parameter passed in. Also, the return of the arrow function has an implied return when there are no brackets.

42. Evaluate the code below. Does it print as intended or throw an error?

const myFunc = ({a, b, c}) => {
  console.log(`${a} ${b} ${c}`);
}

myFunc({a: 'one', b: 'two', c: 'three'});

The code indeed prints one two three as intended. The parameters are passed in and destructured. Then interpolation is used to construct the string.

43. What is the difference between the two imports in the below code?

import Example from 'exampleLib';
import { Example } from 'exampleLib';

In the first import, exampleLib must have this syntax: ‘export default Example…..’. This is what is known as a default export from a package. In the second import, Example is a named export instead of the default export. The exampleLib package would need the following syntax: ‘export const Example….’ Functionally speaking, there’s not much difference other than syntax.

44. What will the code below output and why?

let switcheroo;

switch('abc'){
 case('abc'): 
   switcheroo = 'step 1';
 case('def'):
   switcheroo = 'step 2';
 default:
   switcheroo = 'step 3';
}

console.log(switcheroo);

It will print step 3. Switch statements fall through all remaining steps after the first ‘true’ case they encounter, until the switch statement encounters a break. In the example, there was no break statement, so switcheroo was assigned ‘step 1’, then assign ‘step 2’, then assigned ‘step 3’.

45. True or False? event.preventDefault() stops event propagation.

The answer is False. preventDefault prevents the default action from being taken but does not prevent propogation.

46. What is the syntax for assigning a default parameter value?

It is as simple as parameter b in the below example:

const myFunc = (a, b = 10) => {
  console.log(a * b);
}

myFunc(10); // prints 100
myFunc(10, 20); // prints 200

47. What will the code below output to the console and why?

const obj1 = {
  prop1: 'testA',
  prop2: () => {
    return obj1.prop3;
  },
  prop3: 'testB'
}

console.log(obj1.prop2());

This will output testB. Other properties are accessible within an object’s function properties depending on when the function is invoked.

48. What is the syntax for creating a property that can never be changed in an object?

const obj= {};

Object.defineProperty(obj, 'myProp', {
  value: 'Can't touch this',
  writable: false
});

49. What will the code below output to the console and why?

const myArray = ['thing 1', 'thing 2', 'thing 3'];
myArray.thing4 = 'not a thing';

for(const element in myArray){
  console.log(myArray[element]);
}

The code will print “thing 1”, “thing 2”, “thing 3”, and “not a thing”. It does not fail, but the results may be unexpected. for…in loops through the keys of an object, and in this case thing4 has been added to the myArray object.

50. What does Line 5 of the code below output to the console?

const yourString = '123';
let iterator = yourString[Symbol.iterator]();

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next()); // Line 5
console.log(iterator.next()); // Line 6

Line 5 prints the following:

{
  done: false,
  value: "3"
}

done: true is not printed until Line 6.

Share this post:

4 thoughts on “50 Difficult JavaScript Questions to Test Your JS Knowledge”

  1. let name=’GANESH’
    console.log(name.toUpperCase() ===name);

    I feel this is the best way to check if a string is upper case

    Reply
  2. can you explain from where the value 5 comes into the picture
    const memoryFunction = (x) => {
    const y = x;
    return (z) => {
    console.log(y * z);
    }
    }

    const innerMemoryFunction = memoryFunction(5);

    memoryFunction(6)(6); // Line 8
    innerMemoryFunction(6)(6); // Line 9

    Reply
    • Sure Rohan,

      Take a look at this line:
      const innerMemoryFunction = memoryFunction(5);
      5 is passed into memoryFunction, and y is then assigned a value of 5. This value is ‘remembered’ when the inner function is returned and assigned to innerMemoryFunction.

      Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.