52 Frontend Interview Questions — JavaScript
Introduction
A large number of beginner and experienced developers have started to encounter and notice a problem with job searching. Indeed, the level of competition in the market has become much higher than it was 2–3 years ago.
The best thing to do in the current reality is to keep learning.
In this article, I have compiled 52 questions in a “question:answer” format for frontend developers that I have come across during interviews. The questions are mainly geared towards Junior level and partially towards Middle level.
P.S. Despite the fact that most of the questions are aimed at the Junior level, by preparing for these questions and thoroughly studying the topics, I was able to secure a job as a Middle Frontend Developer.
1. What data types exist in JavaScript?
- Number — Numbers
- String — Strings
- Boolean — Boolean type, true or false
- Object — JavaScript object
- null — a special value that represents “nothing”, “empty”, or “unknown value”.
- undefined — “value has not been assigned”. This type is assigned if a variable is declared but has no assigned value.
- Symbol — a unique and immutable data type that can be used as an identifier for object properties.
- BigInt — used for creating large numbers.
const bigInt = 1234567890123456789012345678901234567890n;
2. What is the difference between “==
” and “===
”?
The operator ==
checks for abstract equality, while ===
checks for strict equality.
In other words, the ==
operator performs necessary type conversions before comparison, whereas ===
does not perform type conversion. Therefore, if two values are not of the same type, it will return false when using the ===
operator.
3. What are the ways to declare a variable?
There are 4 ways to declare a variable:
foo = 123;
var foo = 123;
let a = 123;
const a = 123;
Declaring a variable using the var
keyword is similar to the first method. Variables declared this way have global or function scope and lack block scope, which is a disadvantage.let
and const
are preferable ways to declare variables. They have block scope, meaning that a variable declared inside, for example, a function, will not be visible outside of that function. const
variables are immutable, but if it’s an object, you can change its properties, and if it’s an array, you can modify and add elements.
4. What is the difference between null and undefined?
Both options represent an empty value. If we initialize a variable but don’t assign a value to it, it will be assigned a special marker — undefined. Null is assigned manually.
Null is a special value that represents nothing
, empty
, or unknown value
. If we need to clear the value of a variable, we set foo = null
.
5. Arrow functions and the differences from regular functions.
- Arrow functions cannot use the arguments object.
- They have a different syntax.
- Arrow functions do not have their own this context. When referencing this, an arrow function takes the context from the surrounding scope.
- Arrow functions cannot be used as constructor functions. In other words, they cannot be invoked with the new keyword.
6. What is a closure and why are they needed?
A closure is a function along with all the external variables that it has access to. For example, there is a function that has a nested function which will close over and retain the variables from its parent.
function parent() {
const a = 5;
return function child() {
console.log(5); // child closes over the variable 'a';
}
}
7. What are template literals?
Template literals are enclosed in backticks ()
and allow for multiline strings. They also allow for embedding expressions within them.
const name = 'John';
const text = `User's name is ${name}`;
console.log(text) // User's name is John
8. What are Set and Map?
Map is a collection, a data structure that operates on the principle of key-value pairs, similar to Objects. However, the main difference between Map and Object is that Map allows the use of keys of any type.
Set is a type of collection without keys, an array where each value can only appear once. Set stores unique values within itself.
9. How to check for the presence of a property in an object?
The first way is to use the hasOwnProperty
function
, which is available for every object.
The second way is to use the in operator. However, when using the in operator, caution must be exercised as it checks all prototypes in the chain.
const obj = {
year: 2023,
name: "John"
}
console.log(obj.hasOwnProperty("year")) // true
console.log("year" in obj) // true
console.log("ye" in obj) // false
10. How to access an object property?
The first way is static, using dot notation: obj.a
.
The second way is dynamic, using square brackets: obj[‘a’]
.
const obj = {
year: 2023,
name: "John"
}
console.log(obj['year']) // 2023
console.log(obj.name) // John
11. What are the main methods for working with arrays?
forEach
— an iterative method for looping through the array, does not return anything. It offers a more elegant alternative to a regular for loop.filter(callback, [args])
— a method for filtering an array using a provided function. It creates a new array that includes only the elements from the original array for which the callback(item, i, arr) function returns true.map(callback, [args])
— a method for transforming an array. It creates a new array that consists of the results of calling thecallback(item, i, arr)
function for each element of the array.reduce(callback, [initValue])
— a method for sequentially processing each element of the array while maintaining an intermediate result.
12. What are the ways to create an object?
Using a constructor function:
function User(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const user = new User('John', 'Johnson');
console.log(user); // { firstName: 'John', lastName: 'Johnson' }
Using object literal notation:
const user = {
firstName: 'John',
lastName: 'Johnson'
};
Using a class:
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
const user = new User('John', 'Johnson');
console.log(user); // { firstName: 'John', lastName: 'Johnson' }
Using the create function:
const user = Object.create({
firstName: 'John',
lastName: 'Johnson'
});
13. What is a Promise?
A Promise is an object designed to work with asynchronous code. It maintains its own state. Initially, a Promise is in the pending state, then it transitions to the fulfilled state if the asynchronous code is executed successfully, or to the rejected state if an error occurs. A Promise accepts two callback functions:
onFulfilled
, which is triggered when the Promise is fulfilled.onRejected
, which is triggered when the Promise is rejected.
The usage pattern is as follows:
- The code that needs to perform something asynchronously creates a Promise and returns it.
- The external code, upon receiving the Promise, passes the
onFulfilled
andonRejected
callback functions to it. - Upon completion of the process, the asynchronous code transitions the Promise to the fulfilled or rejected state, automatically invoking the corresponding callback function.
14. What is async/await and how to use it?
async/await
is a special syntax for working with Promises.
A function declared with the async
syntax always returns a Promise.
The keyword await makes the JavaScript interpreter wait until the Promise on the right side of await is fulfilled before continuing the execution. It will then return the result, and the code execution will proceed. await cannot be used in regular functions.
15. How to check if an object is an array?
To check whether an object is an array or not, you can use the Array.isArray()
method. It takes an object as input and returns true if the object is an array, and false if it is not an array.
const obj1 = { person: 'John' }
const obj2 = new Array(2)
const obj3 = []
console.log(Array.isArray(obj1)) // false
console.log(Array.isArray(obj2)) // true
console.log(Array.isArray(obj3)) // true
16. What is the purpose of the spread operator?
The spread operator (…)
is used to unpack arrays or objects.
It allows you to expand elements that are iterable
, such as arrays
and strings
.
- It is used in functions where the expected number of arguments for a call is zero or more.
- It is used in array literals or expressions.
- It is used in object literals where the number of key-value pairs should be zero or more.
const date = [2000, 3, 7]
const newArray = [...date] // [2000, 3, 7]
17. How to avoid reference dependency when copying an object?
If the object does not contain nested objects, for example:
const obj = {
firstName: 'John',
lastName: 'Johnson'
}
In this case, you can use spread operator
or Object.assign()
method:
const copy = {...obj}
// or
const copy = Object.assign({}, obj)
If the object contains nested objects:
const obj = {
data: {
id: 1
}
}
In this case, you need to perform a deep copy.
A workaround, though slower
, is:
const copy = JSON.parse(JSON.stringify(obj))
This method is suitable for objects without prototypes and functions.
Alternatively, you can use the lodash library’s deepClone()
function.
18. How to change the context of a function?
- Using the
bind()
method, which returns a new function with the bound context.
function foo() {
return this
}
const obj = { name: 'John' }
const newFoo = foo.bind(obj)
console.log(newFoo()) // { name: 'John' }
- Using
call()
andapply()
methods. The main difference is thatcall()
accepts a sequence of arguments, whileapply()
accepts an array of arguments as the second parameter.
function foo() {
return this
}
const obj = { name: 'John' }
foo.call(obj, 'arg1', 'arg2') // { name: 'John' }
foo.apply(obj, ['arg1', 'arg2']) // { name: 'John' }
19. What is a ternary operator?
A ternary operator is a shorthand notation for an if-else statement. The operator is represented by a question mark and a colon. It is called ternary because it is the only operator that takes three arguments.
Condition ? Expression_1 : Expression_2
num >= 10 ? 'more than 10' : 'less than 10'
// is equal to
if (num >= 10) {
return 'more than or equal to 10'
}
return 'less than 10'
20. What is destructuring?
Destructuring
is a syntax that allows us to unpack arrays and objects into multiple variables.
const arr = ['John', 'Johnson']
const [firstName, lastName] = arr
console.log(firstName, lastName) // John Johnson
OR
const obj = {
firstName: 'John',
lastName: 'Johnson'
}
const { firstName, lastName } = obj;
console.log(firstName, lastName) // John Johnson
21. What is the DOM?
DOM
stands for Document Object Model
. It is a representation of an HTML
document as a tree of tags.
Example
Each node in the DOM
tree is an object
.
The basic elements of an HTML
document are tags.
According to the Document Object Model (DOM)
, each HTML
tag is an object. Nested tags are children
of their parent element. The text inside a tag is also an object. All these objects are accessible using JavaScript
, and we can use them to manipulate the page.
22. What is the Event Loop?
Event loop
— a mechanism that manages the execution of code. It handles event processing and task execution in the correct order. The main idea of the event loop is that JavaScript runs in a single-threaded environment but can handle asynchronous operations. When an asynchronous operation, such as a server request, completes, it puts the corresponding event into the event queue. The event loop works in a loop, processing these events in the order they arrive. It takes an event from the queue and passes it for execution. If the event contains a callback or a handler, it is invoked, and the code associated with that event is executed. The event loop also handles other tasks, such as timers and microtasks (Promise). It manages the execution order of all these tasks to ensure consistency and prevent the blocking of the main thread of code execution.
In short, the event loop in JavaScript manages asynchronous operations by handling events in the queue and executing the corresponding code in the correct order. This allows JavaScript to be responsive and effectively utilize its resources when working with asynchronous operations.
I highly recommend watching the video at the link provided, as the topic is important and deserves a separate article.
23. What is prototypal inheritance?
Every object in JavaScript has a property — a prototype. Methods and properties can be added to the prototype. Other objects can be created based on the prototype. The created object automatically inherits the methods and properties of its prototype. If a property is absent in the object, its search will be performed in the prototype.
Learn more
24. What is the Optional Chaining operator?
The Optional Chaining operator ?. stops the evaluation and returns undefined if the part after ?. is either undefined or null.
Let’s consider a user object. Most users have an address user.address
, with a street user.address.street
, but some users have not provided an address. In such cases, the Optional Chaining operator can help us avoid an error when trying to access the user’s street who hasn’t specified one in their address.
const user = {};
console.log(user.address.street) // Error!
console.log(user?.address?.street) // undefined. No Error
25. What is Shadow DOM?
Shadow DOM
is a set of web standards that allows for encapsulating the structure and styles of elements on a web page. It represents a special segment of the DOM
that resides inside an element and is separate from the rest of the page. Shadow DOM
is used to create components and widgets with isolated and stylized content that does not conflict with the overall structure of the page.
Learn more
26. What is recursion? How to use it?
Recursion is an approach to problem-solving where a function solves a problem by reusing itself within its own function body. In simple terms, it’s when a function calls itself.
A recursive function consists of:
- Termination condition or base case
- Recursive step — a way to reduce the problem into simpler forms.
function factorial(x) {
if (x === 0) {
return 1;
}
return x * factorial(x - 1);
}
The base case is a necessary condition; otherwise, it will lead to stack overflow due to an infinite loop of function calls.
Learn more
27. What’s the difference between Function Expression and Function Declaration?
Function Declaration is the traditional way of declaring a function.
function foo() {
console.log('Hello World');
}
Function Expression:
let foo = function() {
console.log('Hello World');
}
With Function Declaration, the function is created and assigned to a variable, just like any other value. Essentially, it doesn’t matter how the function is defined, as it is a value stored in the variable “foo”. Function Declarations, however, are processed before the code block is executed, meaning that they are visible throughout the entire code block. On the other hand, Function Expressions are created only when the execution flow reaches them.
28. What are constructor functions?
Constructor functions are regular functions that are used to create objects. However, there are two rules for using them:
- The name of the constructor function should start with a capital letter.
- The constructor function should be called using the new operator.
function User(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
this.role = 'user'
}
const user = new User('John', 'Johnson')
console.log(user.firstName) // John
When a constructor function is created using the new operator, the following happens:
- A new empty object is created and assigned to this.
- The code inside the constructor function is executed. Typically, this code will modify the this object and add new properties.
- The value of this is returned.
29. How can you get a list of keys and a list of values from an object?
You can use Object.keys()
to get a list of keys and Object.values()
to get a list of values.
const user = {
firstName: 'John',
lastName: 'Johnson'
}
const keys = Object.keys(user)
const values = Object.values(user)
console.log(keys) // ['firstName', 'lastName']
console.log(values) // ['John', 'Johnson']
30. Provide an example of new functionality in ES6.
The most common ones:
- let and const. Introduction of new keywords
let
andconst
for declaring variables with block scope. Arrow functions
. The concept of arrow functions allows for more concise and clear function definitions.
function add(a, b) { return a + b } // Regular function
const add = (a, b) => a + b // Arrow function
- Default parameters. You can define default values for function parameters.
function greet(name = 'Anonymous') { console.log(Hello, ${name}!) }
greet(); // "Hello, Anonymous!"
greet('John') // "Hello, John!"
Spread operator (…)
. The spread operator allows unpacking array or object elements for function arguments or creating new arrays/objects.
const numbers = [1, 2, 3];
console.log(...numbers) // 1 2 3
const array1 = [1, 2, 3];
const array2 = [...array1, 4, 5] // [1, 2, 3, 4, 5]
Destructuring
. Destructuring allows extracting values from arrays or objects and assigning them to variables.
const person = { name: 'John', age: 30, city: 'London' }
const { name, age } = person;
console.log(name, age) // "John 30"
const numbers = [1, 2, 3]
const [first, second] = numbers;
console.log(first, second); // 1 2
31. How to do class inheritance in ES6?
Class inheritance is done using the “extends” keyword followed by the name of the parent class.
class User {
firstName = 'John'
lastName = 'Johnson'
}
class Customer extends User {
cart
}
32. What are micro and macro tasks in JavaScript?
In JavaScript, microtasks and macrotasks refer to types of tasks that need to be executed in the event loop. Microtasks are tasks that need to be executed within the current event loop before the browser repaints the page. They are usually added to the execution queue using methods such as Promise.then()
, process.nextTick()
(in Node.js), or MutationObserver
. Examples of microtasks include executing promise handlers and DOM mutations. On the other hand, macrotasks are tasks that need to be executed after the current event loop is finished and before changes are rendered on the screen. This includes tasks added to the event queue using setTimeout
, setInterval
, requestAnimationFrame
, as well as handling input events and network requests. Macrotasks are executed after all microtasks in the current event loop have been processed. The difference between microtasks and macrotasks is important because it determines the order of execution and allows for managing the priority of different tasks in JavaScript. Microtasks have a higher priority and are executed before macrotasks, which allows for faster interface updates and prevents blocking the main JavaScript execution thread.
Learn more
33. What are generators?
Generators produce a sequence of values one by one as needed. Generators work well with objects and make it easy to create data streams.
To declare a generator, a special syntax is used — a generator function.
function* generateSomething() {
yield 10;
yield 20;
yield 30;
return 40;
}
next()
is the main method of a generator. When called, next()
starts executing the code until the nearest yield statement. The value may be absent, in which case it is represented as undefined. When a yield is reached, the function execution is paused, and the corresponding value is returned to the outer code.
let generator = generateSomething();
let first = generator.next();
34. What are the methods of storing data in a browser?
There are several methods of storing data in a browser:
LocalStorage
andSessionStorage
— store key-value pairs in the browser. The data stored in them is retained after the page is refreshed. Both storage options can only use strings as keys and values, so objects need to be converted usingJSON.stringify()
.Cookie
— small strings of data that are stored in the browser. Cookies are usually set by the web server using the Set-Cookie header. The browser will then automatically add them to almost every request to the same domain using the Cookie header. One cookie can hold up to 4kb of data. Depending on the browser, more than 20 cookies per site are allowed.IndexedDB
— a built-in database, more powerful thanlocalStorage
. It is a key-value store where multiple types of keys are available and values can be almost anything.IndexedDB
supports transactions for reliability, supports key range queries and indexes, and allows storing more data thanlocalStorage
.IndexedDB
is designed for offline applications and can be combined with Service Workers and other technologies.
Learn more
Learn more
Learn more
35. What is the difference between sessionStorage and localStorage?
SessionStorage
and localStorage
allow storing objects in key-value format in the browser.
The main differences are:
localStorage
can store up to 10 MB of data, whilesessionStorage
can store up to 5 MB.- Data in
localStorage
is not deleted, while data insessionStorage
is deleted when the browser tab is closed. - Data from
localStorage
is accessible from any window, while data fromsessionStorage
is only accessible from the same browser window.
36. What are regular expressions?
Regular expressions are strings defined by special rules and patterns. They are a powerful tool that allows detecting and working with complex constructions within strings.
let str = "We will, we will rock you"
console.log(str.match(/we/gi)) // ['We', 'we']
37. What are WeakSet and WeakMap and how do they differ from Map and Set?
The first difference between WeakMap
and Map is that the keys in WeakMap
must be objects, not primitive values.
The second difference is in the memory storage of the data structures. The JavaScript engine keeps values in memory as long as they are reachable, meaning they can be used.
Usually, object properties, array elements, or other data structures are considered reachable and are kept in memory as long as the data structure exists, even if there are no other references to them.
In the case of WeakMap
and WeakSet
, it works differently. Once an object becomes unreachable, it is removed from the data structure.
38. Why do two objects with the same fields return false when compared?
Objects are compared based on references to the memory area. For JavaScript, test1 and test2 objects are different, even though they have the same fields. Objects are only equal if they are the same object.
const test1 = { value: 3 }
const test2 = { value: 3 }
console.log(test1 == test2) // false
39. Why can we call methods on primitive types?
JavaScript allows working with primitive data types — strings, numbers, etc. — as if they were objects. Primitive data types have methods.
To make this functionality available, each primitive data type has its own wrapper object: String
, Number
, Boolean
, and Symbol
. Thanks to these wrapper objects, primitive data types have different sets of methods, such as toLowerCase()
or toUpperCase()
.
40. How to check which class an object was created from?
You can check which class an object was created from using the instanceof
operator, taking inheritance into account.
class Person {}
const person = new Person()
console.log(person instanceof Person) // true
41. Write code that will log the time spent on the site in seconds every 10 seconds.
let time = 0
setInterval(() => {
time += 10
console.log(time)
}, 10000)
42. What is a pure function?
A pure function is a function that satisfies two conditions:
- Every time the function is called with the same set of arguments, it returns the same result.
- It has no side effects, meaning it does not modify variables outside the function.
function calculate(num) {
return calculate * 0.05;
}
console.log(calculate(15))
//calculate() function will always return the same result if we pass the same parameter
43. What is a higher-order function?
A higher-order function is a function that takes another function as an argument or returns a function as a result.
const nums1 = [1, 2, 3]
const nums2 = nums1.map(function(num) {
return num * 2;
})
console.log(nums2) // [2, 4, 6]
44. Why do we need Promises if we can work with asynchronous code using callbacks?
If we want to asynchronously fetch some data from a server using callback functions, it would result in the following:
func((x) => {
anotherFunc(x, (y) => {
andAnotherFunc(i, (j) => {
// some code
})
})
})
This is called callback hell, as each callback is nested inside another, and each inner callback depends on the parent function.
Using Promises, we can rewrite the code above:
func()
.then((x) => {
return anotherFunc(x)
})
.then((y) => {
return andAnotherFunc(y)
})
.then((i) => {
return i
})
With Promises, the execution sequence is clear, making the code more readable.
Learn more
45. Write your own implementation of the bind method.
To implement it, we can use closure and the apply()
method to bind the function to the context.
function bind(context, func) {
return function(...args) {
func.apply(context, args)
}
}
46. Write a calculator function with methods plus, minus, multiply, divide, and get. The function must work through optional chaining.
function calculator() {
let result = 0;
function plus(val) {
result += val;
return this;
}
function minus(val) {
result -= val;
return this;
}
function divide(val) {
result /= val;
return this;
}
function multiply(val) {
result *= val;
return this;
}
function get() {
console.log(result);
return this;
}
return { plus, minus, divide, multiply, get };
}
let calc = calculator();
calc.plus(2).minus(1).plus(19).divide(2).multiply(3).get(); // 30
47. Write a randomSort function that takes an array of numbers and sorts the array in random order.
You can use the sort()
method and Math.random()
for this.
function randomSort(array) {
return array.sort(() => {
return 0.5 - Math.random();
});
}
const arr = [2, 1, 3, -2, 9]
console.log(randomSort(arr)) // [-2, 2, 1, 3, 9]
console.log(randomSort(arr)) // [2, 1, -2, 9, 3]
console.log(randomSort(arr)) // [-2, 1, 9, 2, 3]
console.log(randomSort(arr)) // [1, -2, 2, 3, 9]
48. Write a deleteGreatestValue function that takes a two-dimensional array of numbers and removes the greatest number from each nested array.
We should iterate through every nested array, get the greatest value of each nested array and delete it.
function deleteGreatestValue(array) {
for (let i = 0; i < array.length; i++) {
const max = Math.max(...array[i]);
const maxIndex = array[i].indexOf(max);
array[i].splice(maxIndex, 1);
}
return array;
}
const arr = [[1, 4, 4], [2, 6, 3], [9, 2, 7]]
console.log(deleteGreatestValue(arr)) // [[1, 4], [2, 3], [2, 7]]
49. Write a sortPeople function that takes an array of strings names and an array of numbers heights, where names[i] == heights[i]. It should sort the names array based on the heights array.
function sortPeople(names, heights) {
const array = [];
for (let [i, name] of names.entries()) {
array.push([name, heights[i]]);
}
return array.sort((a, b) => b[1] - a[1]).map(([name]) => name);
}
const names = ['John', 'Maria', 'Alexa', 'Robert']
const heights = [180, 160, 165, 187]
console.log(sortPeople(names, heights)) // ['Robert', 'John', 'Alexa', 'Maria']
50. Write a subsets function that takes an array of numbers nums and returns all possible variations of arrays from those numbers.
function subsets(nums) {
let result = [[]];
for (let num of nums) { // Iterate through each number in the nums array
const currentSize = result.length; // Get the current size of result to use it in the loop.
for (let i = 0; i < currentSize; i++) {
let subArray = [...result[i], num]; // Create a new subarray by adding the current number to the result[i] element.
result.push(subArray);
}
}
return result; // Return all possible variations of arrays from the numbers.
51. How to reverse a linked list?
Lets create a function reverseLinkedList
that takes a linked list as input and returns the reversed version of that list.
Approach:
- It initializes the result variable with null, which will hold the reversed list.
- It initializes the root variable with head, which points to the start of the list.
- It enters a while loop that continues until root becomes null, indicating the end of the list.
- Inside the loop, it checks if result already has elements. If it does, it creates a new list node with the current value
root.val
and a pointer to the next node result. It then updates result with this new node. - If result doesn’t have any elements yet, it creates a new list node with the current value
root.val
and null as the pointer to the next node. It then updates result with this new node. - After updating result, it moves to the next element in the list by assigning
root.next
to root. - Once the while loop finishes, it returns the reversed list stored in result.
In summary, the function reverses the linked list by iterating through each node from the head to the tail, creating a new list node for each value and updating the pointers accordingly.
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
function reverseLinkedList(node) {
let result = null; // Initialize the result variable with null, it will hold the reversed list.
let root = head; // Initialize the root variable with head, pointing to the start of the list.
// While root is not null (until we reach the end of the list)
while (root) {
if (result) { // If result already has elements
result = new ListNode(root.val, result); // Create a new list node with the current value root.val and a pointer to the next node result. Update result.
} else { // If result doesn't have any elements yet...
result = new ListNode(root.val, null); // Create a new list node with the current value root.val and null as the pointer to the next node. Update result.
}
root = root.next; // Move to the next element in the list.
}
return result; // Return the reversed list.
}
52. How to sort a linked list?
Lets create a function sortList
that takes a linked list as input and returns the sorted version of that list.
Approach:
- Check if the given linked list is empty or not.
- Traverse the linked list and store the node values into an array.
- Sort the array using the built-in sort() method.
- Create a new linked list using the sorted array.
- Return the head of the created linked list.
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
function sortList (head) {
if (!head) {
return null;
}
let root = head;
let arr = [];
while(root){
arr.push(root.val);
root = root.next;
}
arr.sort((a, b) => a - b);
let node = new ListNode(arr[0]);
head = node;
let temp = head;
for(let i = 1; i < arr.length; i++){
let node = new ListNode(arr[i]);
temp.next = node;
temp = temp.next;
}
return head;
};
Conclusion
Preparing for these questions, studying the topics covered, and reviewing relevant resources can improve your chances of successfully passing the interview. This post is part of a series of posts on interview questions.
I look forward to your reactions and comments.
Good luck in your interview!