Hungry for more advanced and tricky JavaScript Interview questions and answers to transform yourself from a Junior JavaScript Developer into a Senior JavaScript Guru before your next tech interview? Search no more! Come along and explore top hardest JavaScript Interview Questions and Answers including ES6, ES2015 for experienced web developer and get your next six-figure job offer.
JavaScript has both strict and type–converting comparisons:
var a = "42";
var b = 42;
a == b; // true
a === b; // falseSome simple equalityrules:
true or false value, avoid == and use ===.0, "", or [] -- empty array), avoid == and use ===.==. Not only is it safe, but in many cases it simplifies your code in a way that improves readability.Function.prototype.bind.Taken word-for-word from MDN:
The
bind()method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
In my experience, it is most useful for binding the value of this in methods of classes that you want to pass into other functions. This is frequently done in React components.
Object.freeze() vs constconst and Object.freeze are two completely different things.
const applies to bindings ("variables"). It creates an immutable binding, i.e. you cannot assign a new value to the binding.const person = {
name: "Leonardo"
};
let animal = {
species: "snake"
};
person = animal; // ERROR "person" is read-onlyObject.freeze works on values, and more specifically, object values. It makes an object immutable, i.e. you cannot change its properties.let person = {
name: "Leonardo"
};
let animal = {
species: "snake"
};
Object.freeze(person);
person.name = "Lima"; //TypeError: Cannot assign to read only property 'name' of object
console.log(person);The question is when a non-boolean value is coerced to a boolean, does it become true or false, respectively?
The specific list of "falsy" values in JavaScript is as follows:
"" (empty string)0, -0, NaN (invalid number)null, undefinedfalseAny value that's not on this "falsy" list is "truthy." Here are some examples of those:
"hello"42true[ ], [ 1, "2", 3 ] (arrays){ }, { a: 42 } (objects)function foo() { .. } (functions)Let's first look at example of each:
// ES5 Function Constructor
function Person(name) {
this.name = name;
}
// ES6 Class
class Person {
constructor(name) {
this.name = name;
}
}For simple constructors, they look pretty similar.
The main difference in the constructor comes when using inheritance. If we want to create a Student class that subclasses Person and add a studentId field, this is what we have to do in addition to the above.
// ES5 Function Constructor
function Student(name, studentId) {
// Call constructor of superclass to initialize superclass-derived members.
Person.call(this, name);
// Initialize subclass's own members.
this.studentId = studentId;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
// ES6 Class
class Student extends Person {
constructor(name, studentId) {
super(name);
this.studentId = studentId;
}
}It's much more verbose to use inheritance in ES5 and the ES6 version is easier to understand and remember.
It’s an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it’s created:
(function IIFE(){
console.log( "Hello!" );
})();
// "Hello!"This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.
Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances. Generator functions are written using the function* syntax. When called initially, generator functions do not execute any of their code, instead returning a type of iterator called a Generator. When a value is consumed by calling the generator's next method, the Generator function executes until it encounters the yield keyword.
The function can be called as many times as desired and returns a new Generator each time, however each Generator may only be iterated once.
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
let iterationCount = 0;
for (let i = start; i < end; i += step) {
iterationCount++;
yield i;
}
return iterationCount;
}They can be used in IIFEs to encapsulate some code within a local scope so that variables declared in it do not leak to the global scope.
(function() {
// Some code here.
})();As a callback that is used once and does not need to be used anywhere else. The code will seem more self-contained and readable when handlers are defined right inside the code calling them, rather than having to search elsewhere to find the function body.
setTimeout(function() {
console.log('Hello world!');
}, 1000);Arguments to functional programming constructs or Lodash (similar to callbacks).
const arr = [1, 2, 3];
const double = arr.map(function(el) {
return el * 2;
});
console.log(double); // [2, 4, 6]I'm now using the following rule of thumb for functions in ES6 and beyond:
function in the global scope and for Object.prototype properties.class for object constructors.=> everywhere else.Why use arrow functions almost everywhere?
To put it simple, generator has two features:
The most important feature in generators — we can get the next value in only when we really need it, not all the values at once. And in some situations it can be very convenient.
.forEach loop and a .map() loop and why you would pick one versus the other?null, undefined or undeclared? How would you go about checking for any of these states?Async/Await and Generators usage to achive same functionalitythis operator inconsistent?Map and WeakMap?Rust has been Stack Overflow’s most loved language for four years in a row and emerged as a compelling language choice for both backend and system developers, offering a unique combination of memory safety, performance, concurrency without Data races...
Clean Architecture provides a clear and modular structure for building software systems, separating business rules from implementation details. It promotes maintainability by allowing for easier updates and changes to specific components without affe...
Azure Service Bus is a crucial component for Azure cloud developers as it provides reliable and scalable messaging capabilities. It enables decoupled communication between different components of a distributed system, promoting flexibility and resili...