Like any other programming language, JavaScript has its nuances. Knowing how to recognize these nuances is what distinguishes a developer who knows JavaScript from a JavaScript developer. Follow along and check 27 tricky and funny JavaScript Interview Questions Full-Stack Developers must know.
Consider:
function makeAdder(x) {
// parameter `x` is an inner variable
// inner function `add()` uses `x`, so
// it has a "closure" over `x`
function add(y) {
return y + x;
};
return add;
}Reference to inner add function returned is able to remember what x value was passed to makeAdder function call.
var plusOne = makeAdder( 1 ); // x is 1, plusOne has a reference to add(y)
var plusTen = makeAdder( 10 ); // x is 10
plusOne(3); // 1 (x) + 3 (y) = 4
plusTen(13); // 10 (x) + 13 (y) = 23 In C and most other common languages, after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed.
In JavaScript, if you declare a function within another function, then the local variables can remain accessible after returning from the function you called.
A closure is a stack frame which is allocated when a function starts its execution, and not freed after the function returns (as if a 'stack frame' were allocated on the heap rather than the stack!). In JavaScript, you can think of a function reference variable as having both a pointer to a function as well as a hidden pointer to a closure.
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);undefined and not defined in JavaScriptIn JavaScript if you try to use a variable that doesn't exist and has not been declared, then JavaScript will throw an error var name is not defined and the script will stop execute thereafter. But If you use typeof undeclared_variable then it will return undefined.
Before starting further discussion let's understand the difference between declaration and definition.
var x is a declaration because you are not defining what value it holds yet, but you are declaring its existence and the need of memory allocation.
var x; // declaring x
console.log(x); //output: undefinedvar x = 1 is both declaration and definition (also we can say we are doing initialisation), Here declaration and assignment of value happen inline for variable x, In JavaScript every variable declaration and function declaration brings to the top of its current scope in which it's declared then assignment happen in order this term is called hoisting.
A variable that is declared but not define and when we try to access it, It will result undefined.
var x; // Declaration
if(typeof x === 'undefined') // Will return trueA variable that neither declared nor defined when we try to reference such variable then It result
not defined.
console.log(y); // Output: ReferenceError: y is not definedfoo between function foo() {} and var foo = function() {}The former is a function declaration while the latter is a function expression. The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behavior as variables). If you try to invoke a function expression before it is defined, you will get an Uncaught TypeError: XXX is not a function error.
Function Declaration
foo(); // 'FOOOOO'
function foo() {
console.log('FOOOOO');
}Function Expression
foo(); // Uncaught TypeError: foo is not a function
var foo = function() {
console.log('FOOOOO');
};You can create a function within an outer function (a closure) that allows you to update a private variable but the variable wouldn't be accessible from outside the function without the use of a helper function.
function counter() {
var _counter = 0;
// return an object with several functions that allow you
// to modify the private _counter variable
return {
add: function(increment) { _counter += increment; },
retrieve: function() { return 'The counter is currently at: ' + _counter; }
}
}
// error if we try to access the private variable like below
// _counter;
// usage of our counter function
var c = counter();
c.add(5);
c.add(9);
// now we can access the private variable in the following way
c.retrieve(); // => The counter is currently at: 14The 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)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.
Currying is when you break down a function that takes multiple arguments into a series of functions that take part of the arguments. Here's an example in JavaScript:
function add (a, b) {
return a + b;
}
add(3, 4); // returns 7This is a function that takes two arguments, a and b, and returns their sum. We will now curry this function:
function add (a) {
return function (b) {
return a + b;
}
}In an algebra of functions, dealing with functions that take multiple arguments (or equivalent one argument that's an N-tuple) is somewhat inelegant. So how do you deal with something you'd naturally express as, say, f(x,y)? Well, you take that as equivalent to f(x)(y) - f(x), call it g, is a function, and you apply that function to y. In other words, you only have functions that take one argument - but some of those functions return other functions (which ALSO take one argument).
A closure is the combination of a function and the lexical environment within which that function was declared. The word "lexical" refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available. Closures are functions that have access to the outer (enclosing) function's variables—scope chain even after the outer function has returned.
Why would you use one?
A higher-order function is any function that takes one or more functions as arguments, which it uses to operate on some data, and/or returns a function as a result. Higher-order functions are meant to abstract some operation that is performed repeatedly. The classic example of this is map, which takes an array and a function as arguments. map then uses this function to transform each item in the array, returning a new array with the transformed data. Other popular examples in JavaScript are forEach, filter, and reduce. A higher-order function doesn't just need to be manipulating arrays as there are many use cases for returning a function from another function. Function.prototype.bind is one such example in JavaScript.
Map
Let say we have an array of names which we need to transform each string to uppercase.
const names = ['irish', 'daisy', 'anna'];The imperative way will be as such:
const transformNamesToUppercase = function(names) {
const results = [];
for (let i = 0; i < names.length; i++) {
results.push(names[i].toUpperCase());
}
return results;
};
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']Use .map(transformerFn) makes the code shorter and more declarative.
const transformNamesToUppercase = function(names) {
return names.map(name => name.toUpperCase());
};
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']Consider:
var foo = function() { // anonymous function assigned to variable foo
// ..
};
var x = function bar(){ // named function (bar) assigned to variable x
// ..
};
foo(); // actual function execution
x();One of the drawback of creating a true private method in JavaScript is that they are very memory inefficient because a new copy of the method would be created for each instance.
var Employee = function (name, company, salary) {
this.name = name || ""; //Public attribute default value is null
this.company = company || ""; //Public attribute default value is null
this.salary = salary || 5000; //Public attribute default value is null
// Private method
var increaseSalary = function () {
this.salary = this.salary + 1000;
};
// Public method
this.dispalyIncreasedSalary = function() {
increaseSalary();
console.log(this.salary);
};
};
// Create Employee class object
var emp1 = new Employee("John","Pluto",3000);
// Create Employee class object
var emp2 = new Employee("Merry","Pluto",2000);
// Create Employee class object
var emp3 = new Employee("Ren","Pluto",2500);Here each instance variable emp1, emp2, emp3 has own copy of increaseSalary private method.
So as recommendation don't go for a private method unless it's necessary.
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?this keyword work? Provide some code examplesbind function?this operator inconsistent?await keyword and the yield keyword? 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...