Cara menggunakan javascript interview challenges

I hope you have found this quick list of common JavaScript interview questions and answers useful. Thank you for reading!

Show
Build composable web applications

Don’t build web monoliths. Use Bit to create and compose decoupled software components — in your favorite frameworks like React or Node. Build scalable and modular applications with a powerful and enjoyable dev experience.

Bring your team to Bit Cloud to host and collaborate on components together, and speed up, scale, and standardize development as a team. Try composable frontends with a Design System or Micro Frontends, or explore the composable backend with serverside components.

I've carefully gone through over 50 resources, I've been through 10 JavaScript interviews, and I've landed a job at a unicorn startup.

And throughout this entire process, I started to see a pattern in the most frequently asked JS interview questions.

In this article, I have tried to list the concepts which will cover 80% of any good JS interview.

So, if you are prepping for your next JS interview this is the perfect cheatsheet for you to review and solidify your skills. Go through this and you'll be ready to rock. 💃

📝Prerequisites

  • Basic knowledge of the web and programming
  • Familiarity with HTML/CSS and JavaScript (especially ES6+ syntax)

Table Of Contents 📜

  • – JS Variables and Array Methods
  • – Scope, Closures, and Hoisting
  • – Prototypes and "this"
  • – Event Loops, Timers, and Promises
  • - Async/defer, Polyfills, Debouncing, and Throttling

Caveat: The focus here will largely be to cover concepts relevant to the interview and not to create a comprehensive booklet for learning the language. Treat this more like a cheatsheet.

If you want to dive in deeply and learn more JS concepts, check out freeCodeCamp's curriculum.

With that out of the way - let's go!

JavaScript Basics 👶

Let's start off with some basic concepts every JS developer needs to know.

Variables in JavaScript 📥

Variables are the building blocks of every programming language. You use them to store values. A variable can be a number, string, and many other types.

Now, JS is a loosely-typed language. You don't have to state the type of variable. You can just declare it, and JS will figure it out on its own.

Now, in JavaScript we have 3 ways to declare variables:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
9,
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
0, and
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
1.

Here are the key differences:

Cara menggunakan javascript interview challenges

Let's try to understand them through examples.

We will cover scope later on. For now, let's focus on the other differences.

var a = 3
var a = 4

console.log(a) // 4 as var variables can be redeclared + updated

let b = 3
let b = 4

console.log(b) // Syntax Error as let variables cannot be redeclared

// If we just do, it will work because it can be updated
b = 4 

const c = 3
const c = 4

console.log(c) // Syntax Error as const variables cannot be redeclared or updated

const d

// Will this throw an error? Go through the table and try to find the answer.

Note: In JavaScript, putting a semi-colon after the end of statement is optional. I will be skipping it here for the sake of readability.

== vs === in JavaScript

Let's compare some variables. There are two ways you can do that.

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
2 only checks for the value

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
3 checks for value + type


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

Arrays in JavaScript

Now that we know a bit about variables, let's move on to arrays and array-methods.

If we have declared a lot of variables, it makes sense to store them somewhere. Otherwise it will be difficult to keep track of all of them. Arrays are one way of storing a variable.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']

But only storing variables in an array is kind of boring. We can do more stuff with this array (like accessing these variables or changing the order in which they are stored or how they are stored).

For that, JS has a lot of methods. Let's look at some of them now.

JavaScript Array Methods 🧰

The most frequently used array methods in JS are:

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4,
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
5,
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
6,
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
7, and
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
8.

Let's cover

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4,
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
5, and
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
8. You can explore more in this helpful article.

The // Return the words with more than 6 letters const words = ['react', 'script', 'interview', 'style', 'javascript'] const ans = words.filter((word) => word.length > 6) console.log(ans) // ['interview', 'javascript'] 4 array method

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4 creates a new copy of the original array. We use it when we want to do something with the elements of the original array but don't want to change it.

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4 iterates over the original array and takes a callback function (which we'll cover later) as an argument. In the callback function, we tell it what to do with the elements.

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]

The // Return the words with more than 6 letters const words = ['react', 'script', 'interview', 'style', 'javascript'] const ans = words.filter((word) => word.length > 6) console.log(ans) // ['interview', 'javascript'] 5 array method

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
5 creates a new array with elements that meet the given condition(s).

Let's look at an example. I have used arrow functions here. If you are a little uncomfortable with functions, you can cover the next section first and come back.

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']

Try to do the exercises yourself first to test your knowledge. If you come up with different or better solutions, let me know!

Generally, a follow up to this: can you do it without the array method?

let newArr = []

for (let i = 0; i < words.length; i++) {
  if (words[i].length > 6) {
    newArr.push(words[i])
  }
}
console.log(newArr)

The // Return the words with more than 6 letters const words = ['react', 'script', 'interview', 'style', 'javascript'] const ans = words.filter((word) => word.length > 6) console.log(ans) // ['interview', 'javascript'] 8 array method

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
8 is very similar to
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4 but has two key differences:

First of all,

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4 returns a new Array, but
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
8 doesn't.

// Return a new array where even numbers are multiplied by 2 
let arr = [1, 2, 3, 4, 5, 6, 7]

function consoleEven(arr) {
  let data = arr.map((num) => (num % 2 === 0 ? num * 2 : num * 1))
  
  console.log(data)  // [1,  4, 3, 8, 5, 12, 7]
}


// ? is the ternary operator. If the condition is true - first statement is returned otherwise the second one.


consoleEven(arr) 


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)

And second, you can do method chaining in

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4 but not in
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
8.


// Convert  the new array back to original

function consoleEven(arr) {
  let data = arr
    .map((num) => (num % 2 === 0 ? num * 2 : num * 1))
    .map((item) => (item % 2 === 0 ? item / 2 : item / 1))
    
  console.log(data)
}

consoleEven(arr)

Note:

// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
4 and
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
8 don't mutate (change) the original array.

Functional Programming in JavaScript 🛠

We have already used functions above. Let's cover them in more detail now.

Just like how we used variables to store values, we can use functions to store a piece of code which we can reuse.

You can make function in two ways:

function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))

Now, let's cover some important concepts related to functions.

Function Scope in JavaScript 🕵️

Scope determines from where the variables are accessible.

There are three types of scope:

  • Global (declaration outside of any function)
  • Function (declaration inside a function)
  • Block (declaration inside a block)

Remember from before that

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
9 is globally scoped whereas
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
0 and
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
1 are block scoped. Let's understand that now.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

0

Closures in JavaScript (❗important) 🔒

We have already used a closure without even realizing it. In the example below,

// Return a new array where even numbers are multiplied by 2 
let arr = [1, 2, 3, 4, 5, 6, 7]

function consoleEven(arr) {
  let data = arr.map((num) => (num % 2 === 0 ? num * 2 : num * 1))
  
  console.log(data)  // [1,  4, 3, 8, 5, 12, 7]
}


// ? is the ternary operator. If the condition is true - first statement is returned otherwise the second one.


consoleEven(arr) 

9 is a closed-over-variable.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

1

This section will have a lot of fancy words, so bear with me. We will cover them one by one.

MDN says:

A function bundled together with its lexical environment forms a closure.

Okay, what is a lexical environment?

It is essentially the surrounding state – the local memory along with the lexical environment of its parent.

Whaaat? 🤯 I know it's a bit of a doozy. Let's understand it with a simple example.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

2

When x is invoked, y is returned. Now, y is waiting to be executed. Kind of like a loaded gun waiting to be shot! 🔫

So, when we finally invoke z, y is invoked. Now, y has to log


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
0 so it first tries to find 🔍 it in the local memory but it's not there. It goes to its parent function. It finds

function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
0 there.

Voila! There you have it - this is closure.

Even when functions are returned (in the above case y) they still remember their lexical scope (where it came from)

Totally unrelated quote for kicks 👻:

They may forget what you said - but they will never forget how you made them feel - Carl W. Buehner

I swear the rest of the article is legit 🤞 Keep reading.

Advantages of Closures in JavaScript 😎

  • Currying

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

3
  • Data Hiding/Encapsulation

Suppose you want to create a counter application. Every time you call it, the count increases by 1. But you don't want to expose the variable outside the function. How to do it?

You guessed it – closures!


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

4

Don't worry about


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 and

function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
3. We have a whole section devoted to them down below.

Disadvantages of Closures in JavaScript 😅

  • Overconsumption of memory or memory leaks can happen.

For example, the closed-over-variable will not be garbage collected. This is because, even if the outer function has run, the returned inner function still has a reference to the closed-over-variable.

Note: Garbage collection basically removes unused variables from the memory automatically.

Hoisting in JavaScript 🚩

This is JavaScript's default behavior of moving declarations to the top of the program.

  • const a = [1,2,3,4,5]
    
    // Create a new array which multiplies every element by 2
    
    const d = a.map(function(item){ return item*2 })
    
    console.log(d) // [2,4,6,8,10]
    
    9 declaration is hoisted up and initialized with
    
    function consoleEven(arr) {
      let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
      console.log(data) // undefined
    }
    
    consoleEven(arr)
    
    5.
  • // Return the words with more than 6 letters
    const words = ['react', 'script', 'interview', 'style', 'javascript']
    
    const ans = words.filter((word) => word.length > 6)
    
    console.log(ans) // ['interview', 'javascript']
    
    0 and
    // Return the words with more than 6 letters
    const words = ['react', 'script', 'interview', 'style', 'javascript']
    
    const ans = words.filter((word) => word.length > 6)
    
    console.log(ans) // ['interview', 'javascript']
    
    1 declarations are hoisted up but not initialized.
  • 
    function consoleEven(arr) {
      let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
      console.log(data) // undefined
    }
    
    consoleEven(arr)
    
    8 definitions are also hoisted up and stored as they are.

Let's look at an example:


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

5

Phew! I am done with functions here, but if you want more check out this amazing talk by Anjana Vakil on functional programming.

Objects in JavaScript 🔮

Just like arrays, objects are a way of storing data. We do so with the help of key-value pairs.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

6


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
9 is the

// Convert  the new array back to original

function consoleEven(arr) {
  let data = arr
    .map((num) => (num % 2 === 0 ? num * 2 : num * 1))
    .map((item) => (item % 2 === 0 ? item / 2 : item / 1))
    
  console.log(data)
}

consoleEven(arr)
0 and

// Convert  the new array back to original

function consoleEven(arr) {
  let data = arr
    .map((num) => (num % 2 === 0 ? num * 2 : num * 1))
    .map((item) => (item % 2 === 0 ? item / 2 : item / 1))
    
  console.log(data)
}

consoleEven(arr)
1 is the

// Convert  the new array back to original

function consoleEven(arr) {
  let data = arr
    .map((num) => (num % 2 === 0 ? num * 2 : num * 1))
    .map((item) => (item % 2 === 0 ? item / 2 : item / 1))
    
  console.log(data)
}

consoleEven(arr)
2. Keys are generally the name of the properties of the object.

We can store all sorts of data like functions inside an object. You can explore more here on the MDN.

What is function consoleEven(arr) { let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1)) console.log(data) // undefined } consoleEven(arr) 2 in JavaScript?

Now, working with objects is different in JS than in other popular programming languages like C++. And to understand that properly, we need a good grasp of the


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 keyword.

Let's try to understand it step-by-step.

In a program, at times, we need a way to point at stuff. Like saying this function right here belongs to this object.


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 helps us get this context.

You will understand what I am saying better when we look at some examples.

For now, think of


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 as something which provides context. And remember this important thing: its value depends on how and where it is called.

I know, I know. A lot of


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 😬. Let's go over all this slowly.

Start a new program and just log


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

7

It will point to the window object.

Now, let's take an example with an object:


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

8

Now,


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 will point to the object. So what's happening here?

In the first example, we had nothing left of the

function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))
0 so it defaulted to the
function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))
1 object. But in this example, we have the object
function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))
2.

If you do:


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

9

We again get the

function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))
1 object. So, we can see that the value of

function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 depends on how and where are we doing the calling.

What we just did above is called Implicit Binding. The value of


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 got bound to the object.

There is another way to use


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2. Explicit binding is when you force a function to use a certain object as its

function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2.

Let's understand why we need explicit binding through an example.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
0

We are using


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 properly, but can you see the problem with the above code?

We are repeating code. And one of the principles of good programming is keep your code DRY! (Don't Repeat Yourself)

So, let's get rid of

function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))
9 and simply do:


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
1


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

00 forced

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

01 to use the second object as its

function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2.

There are a lot of other ways we can do this.

Cara menggunakan javascript interview challenges

Try to solve the given problem yourself.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
2

Finally, remember that I said that there are differences between arrow and regular functions.

The case of


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2 is one of them.

For an arrow function, the value depends on the lexical scope – that is to say, the outer function where the arrow function is declared.

So, if we make the


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

04 from above an arrow function, nothing will work.

Arrow functions basically inherit the parent's context which in the above case is the

function a(){
 console.log('I am a normal function');
 }
 
const b = () => {
console.log('I am an arrow function')
}

// They are essentially the same but with a few differences which we will cover as we go along this tutorial. 

// We can pass variables as arguments

const c = (name) => {
console.log(`My name is ${name}`)
}

// `` template literal are a new addition to the language. Very useful for string formatting. Values are accessed using ${} inside them.


// We can even pass functions as arguments to a function. Will see more on this when we try to understand closures.

const greet = () =>  {
    const prefix = 'Mr'
    return (name) => {
        console.log(`${prefix} ${name}, welcome!`)
    }
}

console.log(greet()('Jack'))
1.

Prototypes and Prototypal Inheritance in JavaScript 👪

Whenever we create anything (like an object or function) in JavaScript, the JS Engine automatically attaches that thing with some properties and methods.

All this comes via


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

06.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

07 is the object where JS is putting it all.

Let's see some examples. Fire up your consoles!


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
3

All this is called a


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

08.

We can do the same with objects and functions as well.

We will always find


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

09 behind the scenes. That's why you may have heard that everything in JS is an object. 🤯

What is Prototypal Inheritance in JavaScript?


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
4

Note: Don't modify prototypes this way. It's just for understanding. Here's the right way to do it.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
5

By doing this,


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

10 gets access to the object's properties. So, now we can do:


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
6

This is prototypal inheritance.

Asynchronous JavaScript ⚡

So, JS is a single-threaded language. Things happen one at a time. Only after one thing is done can we move to the next thing.

But this creates problems in the real world, especially, when we are working with browsers.

For example, when we need to fetch data from the web - often times we don't know how long will it take to get it. And whether we will be able to get the data successfully.

To help with this, asynchronous JS comes into play.

And the most important concept to understand is the event loop.

Event Loops in JavaScript ➰

Instead of providing a half-baked explanation here, I highly recommend watching this video by Philip Roberts if you haven't already:

Learn all about event loops in JS here.

Timers in JavaScript – setTimeout, setInterval, clearInterval ⏱️

I hope you watched the video. It mentioned timers. Let's talk about them more now. These are very frequently asked about in interviews.

The


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

11 method calls a function or evaluates an expression after a specified number of milliseconds.


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

12 does the same for specified intervals.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
7

You use


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

13 to stop the timer.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
8

Let's go over some questions that use these concepts.


let a = 4
const b = 5
var c = 'hello'

const array = [a, b, c]

// or you can just directly do

const arr = [4,5,'hello']
9

Here's a slightly trickier one:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
0

And here's a short explanation of what's going on there: when


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

14 comes again into the picture, the entire loop has run and the value of

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

15 has become 6,

Now, let's say we want the outcome to be 1 2 3 4 5 – what do we do?

Instead of

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
9 ➡️ use
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
0.

Why this will work?

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
9 is globally scoped but
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
0 is locally scoped. So for
// Return the words with more than 6 letters
const words = ['react', 'script', 'interview', 'style', 'javascript']

const ans = words.filter((word) => word.length > 6)

console.log(ans) // ['interview', 'javascript']
0 a new

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

15 is created for every iteration.

Promises in JavaScript (❗important) 🤝

Promises are at the heart of Asynchronous JS.

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

A promise can be in one of these three states:

  • Pending: initial state, neither fulfilled nor rejected
  • Fulfilled: operation was completed successfully
  • Rejected: operation failed
const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
1

Note:


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

22 and

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

23 are just conventional names. Call it pizza🍕 if you like.

Instead of


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

24, we can also use

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

25:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
2

One of the advantages of promises is that they are a much cleaner syntax. Before we had promises, we could easily get stuck in callback hell 🌋

Advanced JavaScript Concepts to Know

📚 Polyfills in JavaScript

A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it. MDN

  • Let's implement it for
    // Return the words with more than 6 letters
    const words = ['react', 'script', 'interview', 'style', 'javascript']
    
    const ans = words.filter((word) => word.length > 6)
    
    console.log(ans) // ['interview', 'javascript']
    
    4:
const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
3

Notice how we use


function consoleEven(arr) {
  let data = arr.forEach((num) => (num % 2 === 0 ? num * 2 : num * 1))
  console.log(data) // undefined
}

consoleEven(arr)
2. Here, we have basically created a new array and are adding values to it.

Async and defer in JavaScript ✔️

These concepts are frequently asked about in interviews by big corporations like Amazon, Walmart, and Flipkart. 🏢

To understand


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

28 and

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

29, we need to have an idea of how browsers render a webpage. First, they parse the HTML and CSS. Then DOM trees are created. From these, a render tree is created. Finally, from the render tree - a layout is created and the painting happens.

For a more detailed look, check out this video.

Async and defer are


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

30 attributes which can be loaded along with the script tags. They are useful for loading external scripts into your web page.

Let's understand with the help of pictures.

Cara menggunakan javascript interview challenges

Cara menggunakan javascript interview challenges

Cara menggunakan javascript interview challenges

Cara menggunakan javascript interview challenges

If there are multiple scripts which are dependant on each other, use


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

29. Defer script are executed in the order which they are defined.

If you want to load external script which is not dependant on the execution of any other scripts, use


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

28.

Note: The async attribute does not guarantee the order of execution of scripts.

Debouncing in JavaScript ⛹️‍♂️

Debouncing is another favorite topic of interviewers.

Let's understand it by creating a search bar.

Demo: https://codesandbox.io/s/debounce-input-field-o5gml

Create a simple input field in


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

33 like this:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
4

Now, in


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

34. Don't forget to add it to

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

33 first:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
5

First, we have selected the input and added an


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

36 to it. Then we created a debounce function which takes a callback function and delay.

Now, inside the debounce function we create a timer using


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

14. Now, this timer's job is to make sure that the next call for

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

38 only happens after 300 ms. This is what debouncing is.

Also, we use


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

39 to remove it. Don't want too many of them hanging out there taking up memory space!

Phew! Lots of theory. Let's do a fun challenge. You must have seen the countdown before a game starts (it goes like 10, 9, 8, .... with some delay in between). Try to write a program for it.

Here's how you'd do it:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
6

Were you able to solve it? Did you do it differently? Let me know your solution.

Throttling in JavaScript 🛑

Let's look at an example again. Suppose that on every window resize event we call an expensive function. Now, we want it such that the expensive function will only be executed once in the given time interval. This is what throttling is.

Create an


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

33 and an

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

34 with the following code:

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
7

Almost the same as debouncing. The key difference is the


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

42 variable. Only, when it's true we are invoking the callback function. And it is set to

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

43 inside the

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

14. So the value is

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

43 only after the desired time limit.

So, what's the difference between debounce and throttling❓

Let's take the search bar 🔍 example from above. When we are debouncing the input field, we are saying to only fetch the data when the difference between two


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

46 events is at least 300 ms.

In the case of throttling, we make a function call only after a certain period of time.

Suppose that you are searching for an encyclopedia in the search bar. The first call is made on


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

47 and it took us 300 ms to reach

let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

48. The next call will be made then only. All the events in between will be ignored.

So, to summarize, debouncing is when the difference between two


let a = 5 // number
let b = '5' // string

console.log(a == b) // true

console.log(a === b) // false

46 events is 300 ms. And throttling is when the difference between two function calls is 300 ms. Basically, the function is called after a certain interval of time.

Storage in JavaScript 💾

Finally, a small but important topic to wrap things up.

localStorage: Data persists even after closing your session

sessionStorage: You lose your data when your session is over, like when you close the browser on the tab.

const a = [1,2,3,4,5]

// Create a new array which multiplies every element by 2

const d = a.map(function(item){ return item*2 })

console.log(d) // [2,4,6,8,10]
8

And we are done! 🏁 I hope you feel more confident about your next JS interview now. I wish you all the best.

If you have any queries / suggestions / feedback, you can reach me on Twitter: https://twitter.com/rajatetc.

🗃️ Main References

  • MDN Docs
  • Akshay Saini
  • Coding Addict
  • Javascript_Interviews

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT

ADVERTISEMENT


Cara menggunakan javascript interview challenges
rajat gupta

software engineer, unacademy • rajatgupta.xyz • twitter.com/rajatetc • development, design, psychology, and startups


If you read this far, tweet to the author to show them you care. Tweet a thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started