{"id":24813717,"url":"https://github.com/rabi-siddique/javascript-interview-questions","last_synced_at":"2026-04-11T13:03:01.787Z","repository":{"id":188218556,"uuid":"678075132","full_name":"rabi-siddique/JavaScript-Interview-Questions","owner":"rabi-siddique","description":"This repository serves as a valuable resource for both aspiring developers and experienced professionals looking to ace JavaScript-focused interviews.","archived":false,"fork":false,"pushed_at":"2023-10-02T16:30:45.000Z","size":315,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T15:51:46.558Z","etag":null,"topics":["interview-preparation","interview-questions","javascript","javascript-interview-questions","nodejs","reactjs"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rabi-siddique.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-13T15:51:55.000Z","updated_at":"2024-01-31T17:32:27.000Z","dependencies_parsed_at":"2023-08-14T10:32:37.620Z","dependency_job_id":"af37f030-4f10-4e84-aa5e-a54d0d7cb120","html_url":"https://github.com/rabi-siddique/JavaScript-Interview-Questions","commit_stats":null,"previous_names":["rabi-siddique/javascript-interview-questions"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabi-siddique%2FJavaScript-Interview-Questions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabi-siddique%2FJavaScript-Interview-Questions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabi-siddique%2FJavaScript-Interview-Questions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rabi-siddique%2FJavaScript-Interview-Questions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rabi-siddique","download_url":"https://codeload.github.com/rabi-siddique/JavaScript-Interview-Questions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245517602,"owners_count":20628373,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["interview-preparation","interview-questions","javascript","javascript-interview-questions","nodejs","reactjs"],"created_at":"2025-01-30T15:51:50.069Z","updated_at":"2025-12-30T22:47:08.585Z","avatar_url":"https://github.com/rabi-siddique.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"Hi! Below, you'll find a compilation of valuable JavaScript interview questions designed to be a helpful resource during your interview preparations.\r\n\r\n## 1-A Closer Look at the + and - Operators\r\n```js\r\nconsole.log(1 + '1' - 1);\r\n```\r\n\r\nCan you guess the behavior of JavaScript's `+` and `-` operators in situations like the one above?\r\nWhen JavaScript encounters `1 + '1'`, it processes the expression using the + operator. One interesting property of the `+` operator is that it prefers string concatenation when one of the operands is a string. In our case, `'1'` is a string, so JavaScript implicitly coerces the numeric value `1` into a string. Consequently, `1 + '1'` becomes `'1' + '1'`, resulting in the string `'11'`.\r\nNow, our equation is `'11' - 1`. The behavior of the `-` operator is quite the opposite. It prioritizes numeric subtraction, regardless of the types of operands. When the operands are not of the number type, JavaScript performs implicit coercion to convert them into numbers. In this case, `'11'` is converted to the numeric value `11`, and the expression simplifies to `11 - 1`.\r\nPutting it all together:\r\n```bash\r\n'11' - 1 = 11 - 1 = 10\r\n```\r\n## 2-Object Coercion\r\n```js\r\nconst obj = {\r\n  valueOf: () =\u003e 42,\r\n  toString: () =\u003e 27\r\n};\r\nconsole.log(obj + '');\r\n```\r\n\r\nOne interesting aspect is how JavaScript handles the conversion of objects into primitive values, such as strings, numbers, or booleans. This is an interesting question which tests whether you know how coercion works with Objects.\r\n\r\nThis conversion is crucial when working with objects in scenarios like string concatenation or arithmetic operations. To achieve this, JavaScript relies on two special methods: `valueOf` and `toString`.\r\n\r\nThe `valueOf` method is a fundamental part of JavaScript's object conversion mechanism. When an object is used in a context that requires a primitive value, JavaScript first looks for the `valueOf` method within the object. In cases where the `valueOf` method is either absent or doesn't return an appropriate primitive value, JavaScript falls back to the `toString` method. This method is responsible for providing a string representation of the object.\r\n\r\nReturning to our original code snippet:\r\n```js\r\nconst obj = {\r\n  valueOf: () =\u003e 42,\r\n  toString: () =\u003e 27\r\n};\r\nconsole.log(obj + '');\r\n```\r\nWhen we run this code, the object `obj` is converted to a primitive value. In this case, the `valueOf` method returns `42`, which is then implicitly converted to a string due to the concatenation with an empty string. Consequently, the output of the code will be:\r\n```bash\r\n42\r\n```\r\nHowever, in cases where the valueOf method is either absent or doesn't return an appropriate primitive value, JavaScript falls back to the `toString` method. Let's modify our previous example:\r\n```js\r\nconst obj = {\r\n  toString: () =\u003e 27\r\n};\r\nconsole.log(obj + '');\r\n```\r\nHere, we've removed the `valueOf` method, leaving only the `toString` method, which returns the number `27`. In this scenario, JavaScript will resort to the `toString` method for object conversion.\r\n\r\n## 3-The Double Equals Operator\r\n```js\r\nconsole.log([] == ![]);\r\n```\r\n\r\nThis one is a bit complex. So, what do you think will be the output? Let's evaluate this step by step. Let's first start by seeing the types of both operands:\r\n```js\r\ntypeof([]) // \"object\"\r\ntypeof(![]) // \"boolean\"\r\n```\r\n\r\nFor `[]` it is an object, which is understandable. As everything in JavaScript is an object including arrays and functions. But how does the operand `![]` has a type of boolean? Let's try to understand this. When you use `!` with a primitive value, the following conversions happen:\r\n- **Falsy Values**: If the original value is a falsy value (such as `false`, `0`, `null`, `undefined`, `NaN`, or an empty string `''`), applying `!` will convert it to `true`.\r\n- **Truthy Values**: If the original value is a truthy value (any value that is not falsy), applying `!` will convert it to `false`.\r\n\r\nIn our case `[]` is an empty array, which is a truthy value in JavaScript. Since `[]` is truthy, `![]` becomes false. So our expression becomes:\r\n\r\n```js\r\n[] == ![]\r\n[] == false\r\n```\r\n\r\nNow let's move ahead and understand the `==` operator. Whenever 2 values are compared using `==` operator, JavaScript performs the **Abstract Equality Comparison Algorithm**. The algorithm has the following steps:\r\n![Abstract Equality Comparison Algorithm](/images/abstractEquality.png \"Abstract Equality Comparison Algorithm\")\r\n\r\nAs you can see this algorithm takes into account the types of the compared values and performs necessary conversions. \r\nFor our case, let's denote `x` as `[]` and `y` as `![]`. We inspected the types of `x` and `y` and found `x` as an object and `y` as boolean. Since `y` is a boolean and `x` is an object, condition 7 from the abstract equality comparison algorithm is applied:\r\n\u003e If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).\r\n\r\nMeaning if one of the types is a boolean, we need to convert it into a number before comparison. What's the value of **ToNumber(y)**? As we saw, `[]` is a truthy value, negating makes it `false`. As a result, **Number(false)** is `0`. \r\n```js\r\n[] == false\r\n[] == Number(false)\r\n[] == 0\r\n```\r\n\r\nNow we have the comparison `[] == 0` and this time condition 8 comes into play:\r\n\u003e If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).\r\n\r\nBased on this condition, if one of the operands is an object, we need to convert it into a primitive value. This is where the **ToPrimitive** algorithm comes into the picture. We need to convert `x` which is [] to a primitive value. Arrays are objects in JavaScript. And we saw earlier that when converting objects to primitives, `valueOf` and `toString` methods come into play. In this case, `valueOf` returns the array itself which is not a valid primitive value. As a result, we move to `toString` for an output. Applying the `toString` method to an empty array results in obtaining an empty string, which is a primitive:\r\n```js\r\n[] == 0\r\n[].toString() == 0\r\n\"\" == 0\r\n```\r\n\r\nConverting the empty array to a string gives us an empty string, `\"\" ` and now we face the comparison: `\"\" == 0`.\r\nNow that one of the operands is of the type string and the other one is of the type number,  condition 5 holds:\r\n\u003e If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.\r\n\r\nHence, we need to convert the empty string, `\"\"` to a number, which gives us a `0`.\r\n\r\n```js\r\n\"\" == 0\r\nToNumber(\"\") == 0\r\n0 == 0\r\n```\r\n\r\nFinally, both operands have the same type and condition 1 holds. As both have the same value, the final output is: \r\n```js\r\n0 == 0 // true\r\n```\r\n\r\n## 4-Understanding Object Keys\r\nWhen working with objects in JavaScript, it's important to grasp how keys are treated and assigned within the context of other objects. Consider the following code snippet and take some time to guess the output:\r\n```js\r\nlet a = {};\r\nlet b = { key: 'test' };\r\nlet c = { key: 'test' };\r\na[b] = '123';\r\na[c] = '456';\r\nconsole.log(a);\r\n```\r\nAt first glance, it might seem like this code should produce an object a with two distinct key-value pairs. However, the outcome is quite different due to JavaScript's handling of object keys.\r\nJavaScript employs the default `toString()` method to convert object keys into strings. But why? In JavaScript, object keys are always strings, or they are automatically converted to strings via implicit coercion. When you use any value other than a string (e.g., a number, object, or symbol) as a key in an object, JavaScript will internally convert that value to its string representation before using it as a key.\r\nConsequently, when we use objects `b` and `c` as keys in the object `a`, both are transformed into the same string representation: `[object Object]`. Due to this behavior, the second assignment, `a[b] = '123';` will overwrite the first assignment `a[c] = '456';`. Let's break down the code step by step:\r\n1. `let a = {};`: Initializes an empty object `a`.\r\n2. `let b = { key: 'test' };`: Creates an object `b` with a property `key` having the value `'test'`.\r\n3. `let c = { key: 'test' };`: Defines another object `c` with the same structure as `b`.\r\n4. `a[b] = '123';`: Sets the value `'123'` to the property with key `[object Object]` in object `a`.\r\n5. `a[c] = '456';`: Updates the value to `'456'` for the same property with key `[object Object]` in object `a`, replacing the previous value.\r\n\r\nBoth assignments utilize the identical key string `[object Object]`. As a result, the second assignment overwrites the value set by the first assignment. When we log the object `a`, we observe the following output:\r\n```bash\r\n{ '[object Object]': '456' }\r\n```\r\n\r\n## 5-Closures\r\nThis is one of the most famous interview questions asked related to closures:\r\n\r\n```js\r\nconst arr = [10, 12, 15, 21];\r\nfor (var i = 0; i \u003c arr.length; i++) {\r\n  setTimeout(function() {\r\n    console.log('Index: ' + i + ', element: ' + arr[i]);\r\n  }, 3000);\r\n}\r\n```\r\n\r\nIf you know the output, then well and good. So let's try to understand this snippet. At the face value, it looks that this snippet would give us the output of:\r\n\r\n```bash\r\nIndex: 0, element: 10\r\nIndex: 1, element: 12\r\nIndex: 2, element: 15\r\nIndex: 3, element: 21\r\n```\r\nBut this is not the case over here. Due to the concept of closures and how JavaScript handles variable scope, the actual output will be different. When the `setTimeout` callbacks are executed after the delay of 3000 milliseconds, they will all reference the same variable `i`, which will have a final value of `4` after the loop has completed. As a result, the output of the code will be:\r\n\r\n```bash\r\nIndex: 4, element: undefined\r\nIndex: 4, element: undefined\r\nIndex: 4, element: undefined\r\nIndex: 4, element: undefined\r\n```\r\n\r\nThis behavior occurs because the `var` keyword does not have block scope, and the `setTimeout` callbacks capture the reference to the same `i` variable. When the callbacks execute, they all see the final value of `i`, which is `4`, and try to access `arr[4]`, which is `undefined`.\r\n\r\nTo achieve the desired output, you can use the `let` keyword to create a new scope for each iteration of the loop, ensuring that each callback captures the correct value of `i`:\r\n\r\n```js\r\nconst arr = [10, 12, 15, 21];\r\nfor (let i = 0; i \u003c arr.length; i++) {\r\n  setTimeout(function() {\r\n    console.log('Index: ' + i + ', element: ' + arr[i]);\r\n  }, 3000);\r\n}\r\n```\r\n\r\nWith this modification, you will get the expected output:\r\n\r\n```bash\r\nIndex: 0, element: 10\r\nIndex: 1, element: 12\r\nIndex: 2, element: 15\r\nIndex: 3, element: 21\r\n```\r\n\r\nUsing `let` creates a new binding for `i` in each iteration, ensuring that each callback refers to the correct value.Often, developers have become familiar with the solution involving the `let` keyword. However, interviews can sometimes take a step further and challenge you to solve the problem without using `let`. In such cases, an alternative approach involves creating a closure by immediately invoking a function(IIFE) inside the loop. This way, each function call has its own copy of `i`. Here's how you can do it:\r\n\r\n```js\r\nconst arr = [10, 12, 15, 21];\r\nfor (var i = 0; i \u003c arr.length; i++) {\r\n  (function(index) {\r\n    setTimeout(function() {\r\n      console.log('Index: ' + index + ', element: ' + arr[index]);\r\n    }, 3000);\r\n  })(i);\r\n}\r\n```\r\n\r\nIn this code, the immediately invoked function `(function(index) { ... })(i);` creates a new scope for each iteration, capturing the current value of `i` and passing it as the `index` parameter. This ensures that each callback function gets its own separate `index` value, preventing the closure-related issue and giving you the expected output:\r\n\r\n```bash\r\nIndex: 0, element: 10\r\nIndex: 1, element: 12\r\nIndex: 2, element: 15\r\nIndex: 3, element: 21\r\n```\r\n## 6-Duplicating Array Elements\r\n\r\nConsider the following JavaScript code and try to find any issues in this code:\r\n\r\n```js\r\nfunction duplicate(array) {\r\n  for (var i = 0; i \u003c array.length; i++) {\r\n    array.push(array[i]);\r\n  }\r\n  return array;\r\n}\r\n\r\nconst arr = [1, 2, 3];\r\nconst newArr = duplicate(arr);\r\nconsole.log(newArr);\r\n```\r\n\r\nIn this code snippet we are required to create a new array containing the duplicated elements of the input array. Upon initial inspection, the code appears to aim for the creation of a new array, `newArr`, by duplicating each element from the original array `arr`. However, a critical issue arises within the `duplicate` function itself.\r\n\r\nThe `duplicate` function uses a loop to go through each item in the given array. But inside the loop, it tries to add a copy of each item at the end into the same array, using the `push()` method. This makes the array longer each time, creating a problem where the loop never stops. The part that checks if the loop should continue `(i \u003c array.length)` always stays true because the array keeps getting bigger. This makes the loop go on forever, causing the program to get stuck.\r\n\r\nTo address the problem of the infinite loop caused by the growing array length, you can store the initial length of the array in a variable before entering the loop. Then, you can use this initial length as the limit for the loop iteration. This way, the loop will only run for the original elements in the array and won't be affected by the array's growth due to duplicates being added. Here is the modified version of the code:\r\n\r\n```js\r\nfunction duplicate(array) {\r\n  var initialLength = array.length; // Store the initial length\r\n  for (var i = 0; i \u003c initialLength; i++) {\r\n    array.push(array[i]); // Push a duplicate of each element\r\n  }\r\n  return array;\r\n}\r\n\r\nconst arr = [1, 2, 3];\r\nconst newArr = duplicate(arr);\r\nconsole.log(newArr);\r\n```\r\n\r\nBy using the `initialLength` variable as the loop limit, it ensures that the loop runs only for the original elements and doesn't get caught in an infinite loop due to the array's expansion.\r\nThe output will show the duplicated elements at the end of the array, and the loop won't result in an infinite loop:\r\n\r\n```bash\r\n[1, 2, 3, 1, 2, 3]\r\n```\r\n\r\n## 7-Scopes\r\nWhen writing JavaScript code, it's important to understand the concept of scope. Scope refers to the accessibility or visibility of variables within different parts of your code. Before we proceed with the example, if you're not familiar with hoisting and how JavaScript code is executed, you can learn about it from this [link](https://blog.devgenius.io/hoisting-in-javascript-c90f6d03d2df). This will help you understand how JavaScript code works in more detail.\r\nLet's take a closer look at the code snippet:\r\n\r\n```js\r\nfunction foo() {\r\n    console.log(a);\r\n}\r\n  \r\nfunction bar() {\r\n    var a = 3;\r\n    foo();\r\n}\r\n\r\nvar a = 5;\r\nbar();\r\n```\r\n\r\nThe code defines 2 functions `foo()` and `bar()` and a variable `a` with a value of `5`. All these declarations happen in the global scope. Inside the `bar()` function, a variable `a` is declared and assigned the value `3`. So when the `bar()` function is called, what value of `a` do you think it will print? \r\n\r\nWhen the JavaScript engine executes this code, the global variable `a` is declared and assigned the value `5`. Then the `bar()` function is called. Inside the `bar()` function, a local variable `a` is declared and assigned the value `3`. This local variable `a` is distinct from the global variable `a`. After that the `foo()` function is called from within the `bar()` function.\r\n\r\nInside the `foo()` function, the `console.log(a)` statement tries to log the value of `a`. Since there is no local variable `a` defined within the `foo()` function's scope, JavaScript looks up the scope chain to find the nearest variable named `a`. The scope chain refers to all the different scopes that a function has access to when it's trying to find and use variables.\r\n\r\nNow, let's address the question of where JavaScript will search for the variable `a`. Will it look within the scope of the `bar` function, or will it explore the global scope? As it turns out, JavaScript will search in the global scope, and this behavior is driven by a concept called **lexical scope**.\r\n\r\nLexical scope essentially refers to the scope of a function or variable at the time it was written in the code. When we defined the `foo` function, it was given access to both its own local scope and the broader global scope. This characteristic remains consistent no matter where we call the `foo` function-whether it's inside the bar function, or if we export it to another module and run it there. Lexical scope is not determined where we call the function.\r\n \r\nThe upshot of this is that the output will always be the same: the value of `a` found in the global scope, which in this case is `5`.\r\n\r\nHowever, if we had defined the `foo` function within the bar function, a different scenario emerges:\r\n\r\n```js\r\nfunction bar() {\r\n  var a = 3;\r\n\r\n  function foo() {\r\n    console.log(a);\r\n  }\r\n  \r\n  foo();\r\n}\r\n\r\nvar a = 5;\r\nbar();\r\n```\r\n\r\nIn this situation, the lexical scope of foo would encompass three distinct scopes: its own local scope, the scope of the bar function, and the global scope. Lexical scope is determined by where you place your code in the source code during compile time.\r\n\r\nWhen this code runs, `foo` is situated within the `bar` function. This arrangement alters the scope dynamics. Now, when `foo` attempts to access the variable `a`, it will first search within its own local scope. Since it doesn't find `a` there, it will broaden its search to the scope of the `bar` function. Lo and behold, `a` exists there with the value `3`. As a result, console statement would print `3`.\r\n\r\n## 8-Difference between prototype and `__proto__`\r\nThe `prototype` property is an attribute associated with constructor functions in JavaScript. Constructor functions are used to create objects based on a blueprint. When you define a constructor function, you can also attach properties and methods to its `prototype` property. These properties and methods then become accessible to all instances of objects created from that constructor. Essentially, the `prototype` property serves as a **common repository** for methods and properties that are shared among instances.\r\nConsider the following code snippet:\r\n\r\n```js\r\n// Constructor function\r\nfunction Person(name) {\r\n  this.name = name;\r\n}\r\n\r\n// Adding a method to the prototype\r\nPerson.prototype.sayHello = function() {\r\n  console.log(`Hello, my name is ${this.name}.`);\r\n};\r\n\r\n// Creating instances\r\nconst person1 = new Person(\"Haider Wain\");\r\nconst person2 = new Person(\"Omer Asif\");\r\n\r\n// Calling the shared method\r\nperson1.sayHello();  // Output: Hello, my name is Haider Wain.\r\nperson2.sayHello();  // Output: Hello, my name is Omer Asif.\r\n```\r\n\r\nIn this example, we have a constructor function named `Person`. By extending the `Person.prototype` with a method like `sayHello`, we're adding this method to the prototype chain of all `Person` instances. This allows each instance of `Person` to access and utilize the shared method. Instead of each instance having its own copy of the method. \r\n\r\nOn the other hand, the `__proto__` property, often pronounced as \"dunder proto,\" exists in every JavaScript object. In JavaScript, everything, except primitive types, can be treated as an object. Each of these objects has a prototype, which serves as a reference to another object. The `__proto__` property is simply a reference to this prototype object. The prototype object is used as a fallback source for properties and methods when the original object doesn't possess them. By default, when you create an object, its prototype is set to `Object.prototype`.\r\n\r\nWhen you attempt to access a property or method on an object, JavaScript follows a lookup process to find it. This process involves two main steps:\r\n\r\n1. Object's Own Properties: JavaScript first checks if the object itself directly possesses the desired property or method. If the property is found within the object, it's accessed and used directly.\r\n2. Prototype Chain Lookup: If the property is not found in the object itself, JavaScript looks at the object's prototype (referenced by the `__proto__` property) and searches for the property there. This process continues recursively up the prototype chain until the property is found or until the lookup reaches the `Object.prototype`.\r\n\r\nIf the property is not found even in the `Object.prototype`, JavaScript returns `undefined`, indicating that the property does not exist.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frabi-siddique%2Fjavascript-interview-questions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frabi-siddique%2Fjavascript-interview-questions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frabi-siddique%2Fjavascript-interview-questions/lists"}