Interview - Js - Questions Preview
Interview - Js - Questions Preview
js
05. Deep Flatten I - Easy
06. Deep Flatten II - Easy
07. Deep Flatten III - Easy
w.
08. Deep Flatten IV - Hard
09. Negative Indexing in Arrays (Proxies) - Medium
10. Implement a Pipe Method - Easy
e
11. Implement Auto-retry Promises - Medium
12. Implement Promise.all - Medium
vi
13. Implement Promise.allSettled - Medium
14. Implement Promise.any - Medium
r
15. Implement Promise.race - Easy
te
js
34. Implement Custom Deep Clone - Medium
35. Promisify the Async Callbacks - Easy
w.
36. Implement 'N' async tasks in Series - Hard
37. Implement 'N' async tasks in Parallel - Medium
38. Implement 'N' async tasks in Race - Easy
e
39. Implement Custom Object.is() method - Easy
40. Implement Custom lodash _.partial() - Medium
vi
41. Implement Custom lodash _.once() - Medium
42. Implement Custom trim() operation - Medium
43. Implement Custom reduce() method - Medium
r
44. Implement Custom lodash _.memoize() - Medium
te
Problem Statement
js
own version.
w.
What does `Object.assign()` do?
Note:
const target = { a: 1, b: 2 };
const source = { c: 4, d: 5 };
objectAssign(target, source);
console.log(target);
// { a: 1, b: 2, c: 4, d: 5 }
js
// --------------------------------------
w.
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 30 };
const source3 = { d: 40 };
e
objectAssign(target, source1, source2, source3);
vi
console.log(target);
// { a: 1, b: 2, c: 30, d: 40 }
r
// --------------------------------------
te
// When target and the source has the same property name, the
value of source's property will override the value in target
In
const target = { a: 1, b: 20 };
const source1 = { b: 2, c: 3 };
const source2 = { c: 30, d: 4 };
console.log(target);
// { a: 1, b: 2, c: 30, d: 4 }
// --------------------------------------
const target = { a: 1 };
const source = { b: 5 };
const returnedTarget = objectAssign(target, source);
js
Concepts
w.
Before jumping straight away to the solution or
implementation we need to understand a few concepts which
are important for the problem.
e
1. Objects - Property Flags and descriptors :
vi
On a general note we know, objects can store properties,
where each property is a “key-value” pair. But there’s more to
object properties.
r
te
Property Flags :
We know the fact that in an object a key has a value. But the
fact is the value which we have mapped to a `key` in the
In
const user = {
name: "Peter"
}
js
information about a property) for the property 'name' from the
object 'user'
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
w.
console.log(descriptor);
/* This below object is basically called as 'property
descriptor'
{
e
value: 'Peter', // This what we were talking about
writable: true,
vi
enumerable: true,
configurable: true
}
r
*/
te
js
const user = {
age: 20
}
w.
// `writable` set to false
Object.defineProperty(user, 'name', {
value: 'Peter',
writable: false,
enumerable: true,
e
vi
configurable: true
})
r
console.log(user.name); // Peter
user.name = 'Parker';
te
console.log(user.name); // Peter
console.log(user.name); // Parker
user.name = 'Parker';
console.log(user.name); // Parker
// -------------------------------------------
const user = {
age: 20,
dept: 'cse'
}
js
// `enumerable` set to false
Object.defineProperty(user, 'name', {
value: 'Peter',
w.
writable: true,
enumerable: false,
configurable: true
})
e
for (let key in user) {
console.log(key);
vi
}
// 'age', 'dept'
r
console.log(Object.keys(user));
// ['age', 'dept'] - 'name' property will be ignored
te
console.log(Object.keys(user));
// ['age', 'dept', 'name']
// -------------------------------------------
const user = {
js
age: 20,
}
w.
// `configurable` set to false
Object.defineProperty(user, 'name', {
value: 'Peter',
writable: true,
})
enumerable: true,e
configurable: false
vi
// Let's try redefining the descriptors of the property 'name'
r
// trying `writable` set to false
te
Object.defineProperty(user, 'name', {
value: 'Parker',
writable: false,
In
enumerable: true,
configurable: true
})
// throws [Error]: Cannot redefine property: name
js
writable: true,
enumerable: true,
configurable: true
w.
})
// throws [Error]: Cannot redefine property: name
// Yes, we can't also change the `configured` flag back to true
2. Ownership:
e
Ownership determines whether a property belongs to an
vi
object directly or is inherited from its prototype chain. It is
important to differentiate between own and inherited
r
properties.
te
js
const obj = { name: 'Peter' };
console.log(obj.hasOwnProperty('name')); // true
console.log(Object.hasOwn(obj, 'name')); // true
w.
const newObj = { age: 20 };
e
const parent = { name: 'Peter' };
vi
Object.setPrototypeOf(newObj, parent);
console.log(newObj.hasOwnProperty('name')); // false
console.log(Object.hasOwn(newObj, 'name')); // false
r
console.log(newObj.hasOwnProperty('age')); // true
te
3. Symbols :
(Although the concept of how `Symbol` works is not that
necessary to be known to solve this problem, but it’s definitely
a good-to-learn)
Only two primitive types are allowed to be used as keys in
objects.
➔string type
➔symbol type
js
Symbols basically are "always" a unique value returned.
w.
Symbols can be used to be used as a key in an object.
// You can't see what the value is, since it's meant to be
private as per spec e
// Instead it just prints `Symbol()`
vi
let sym = Symbol();
console.log(sym); // Symbol()
js
the same Symbol value
console.log(Symbol.for('world')); // Symbol(world)
console.log(Symbol.for('world') === Symbol.for('world')); //
w.
true
console.log(obj);
r
// { name: 'Peter', [Symbol(age)]: 19 }
te
Note: Any string type property used as key for an object will
be `enumerable` as `true` by default (i.e. while looping the key
will be shown). But the Symbol type property used as key on
the other hand will have the enumerable as `false` by default
(i.e. while looping the key will not be shown). As per the spec,
Symbol type is non-enumerable since it indicates private
information.
Implementation
js
1. If the target is not a valid object like `null` or `undefined` it
should throw an exception.
w.
2. Loop over all the source objects individually and collect
all properties (keys) of the source object both
enumerable and non-enumerable. Assign only the
e
enumerable properties.
3. If the target and both source objects have the same
vi
property (key) and if the property in the target object has
the flag writable set to `false` then we should throw an
exception.
r
te
js
// Using the Object constructor to wrap and turn
primitives like number, boolean, string, BigInt, NaN into its
wrapper Object form
w.
source = Object(source);
to target`);
}
return target;
}
Test Cases
js
const target = null;
const source = { name: 'Hello' };
w.
objectAssign(target, source);
// Error: target should not be null or undefined
// -------------------------------------------
console.log(objectAssign(target, source));
// { name: 'Hello' }
r
te
// -------------------------------------------
console.log(objectAssign(target, source));
// { name: 'Hello' }
// -------------------------------------------
console.log(objectAssign(target, source));
// { name: 'Hello' }
// -------------------------------------------
const target = { a: 1, b: 2 };
const source = { c: 30, d: -1 };
console.log(objectAssign(target, source));
// { a: 1, b: 2, c: 30, d: -1 }
js
// -------------------------------------------
w.
const target = { a: 1, b: 2 };
const source = { c: 30, b: -1 };
console.log(objectAssign(target, source));
e
// { a: 1, b: -1, c: 30 }
// -------------------------------------------
vi
const target = { a: 1, b: 2 };
const source1 = { c: 40, d: -1 };
r
const source2 = { e: 50, a: 0 };
const source3 = { f: 3, f: -1 };
te
// -------------------------------------------
console.log(objectAssign(target, source));
// { name: 'Peter' } - 'age' doesn't appear since non-enumerable
// -------------------------------------------
js
Object.defineProperty(target, 'name', {
value: 'Parker',
writable: false,
w.
enumerable: true,
configurable: true
});
console.log(target); e
// { name: 'Parker', age: '19' }
vi
const source = { name: 'Spiderman', age: '19' };
console.log(objectAssign(target, source));
r
// Error: Property name is not writable to target
te
// -------------------------------------------
const target = { a: 1, b: 2 };
In
// -------------------------------------------
const target = { name: 'Spiderman', age: '19' };
js
});
console.log(source);
w.
// { age: '29', [Symbol(name)]: 'Peter' }
console.log(objectAssign(target, source));
// { name: 'Spiderman', age: '29', [Symbol(name)]: 'Peter' }
e
// -------------------------------------------
vi
const target = { name: 'Spiderman', age: '19' };
value: 'Peter',
writable: true,
enumerable: false,
In
configurable: true
});
console.log(source);
// { age: '29' }
console.log(objectAssign(target, source));
// { name: 'Spiderman', age: '29' }
Implement Custom lodash _.get()
Problem Statement
js
The `get()` method accepts 3 parameters as input - object,
w.
path, defaultValue.
// Syntax
function get(obj, path, defaultValue) {}
In
Example
const obj = {
a: {
b: 'Hello',
c: null,
d: [1, 2, 'World'],
e: [
{ name: 'Peter Parker' },
{ work: 'Spiderman' }
],
h: {
i: {
j: 'Iron Man',
k: 'Batman'
}
js
}
},
f: {
w.
g: undefined
}
}
e
get(obj, 'a.h.i.j', 'Key Not Found');
// Iron Man
vi
get(obj, 'a.c', 'Key Not Found');
// null
r
get(obj, 'f.g.h.i', 'Key Not Found');
// Key Not Found
te
Implementation
js
a valid array of keys.
➔Then evaluate the current key for its existence in the
w.
object.
➔If all the keys are traversed or processed in the object,
return the value, else recursively continue processing to
get the value. e
vi
The first thing we need to do is to parse the input to a
common notation. That is, we don’t want square brackets, so
replace them with dot notation.
r
te
js
// First step is to replace all of the square bracket
notation [] with dot notation
// This will work for accessing values from both Objects and
w.
arrays
let keys = [];
if (!Array.isArray(path)) {
path = path.replaceAll('[', '.');
e
path = path.replaceAll(']',
keys = path.split('.');
'');
vi
}
else {
keys = path;
r
}
te
if (keys.length === 1) {
// We use `hasOwnProperty` method to check if a key
exists on the object
// Using `obj[currKey]` is not good, since there can be a
falsy value as well like null, undefined, '' (which are
completely valid)
// So the aim should be to check if the property was
defined on the object or not
return obj.hasOwnProperty(currKey) ? obj[currKey] :
defaultValue;
}
else {
// Recursively continue traversing the path on the object
to get the value
if (obj.hasOwnProperty(currKey)) {
return get(obj[currKey], keys.slice(1),
defaultValue);
}
js
return defaultValue;
}
}
w.
Test Cases
const obj
a: {
= { e
vi
b: 'Hello',
c: null,
d: [1, 2, 'World'],
e: [
r
{ name: 'Peter Parker' },
te
{ work: 'Spiderman' }
],
h: {
i: {
In
j: 'Iron Man',
k: 'Batman'
}
}
},
f: {
g: undefined
}
}
console.log(get(obj, 'a.b', 'Key Not Found'));
// Hello
js
console.log(get(obj, ['a', 'e', '1', 'work'], 'Key Not Found'));
// Spiderman
w.
console.log(get(obj, 'a[d].1', 'Key Not Found'));
// 2
Problem Statement
js
This problem is exactly the same as those of the previous
w.
problems, 46. Implement Custom call() method and 47.
Implement Custom apply() method
e
Recommend you to go through those first and understand the
concepts discussed.
vi
The `bind()` method takes an object as the first argument and
sets it as the "this" context (kind of permanently) for the
r
function which needs to be invoked.
te
js
const spidermanObj = {
firstname: "Peter",
lastname: "Parker",
w.
printName
}
printSpiderman();
e
vi
// Peter Parker - spiderman - NY
printSpiderman();
r
// Peter Parker - spiderman - NY
te
const ironmanObj = {
firstname: "Tony",
lastname: "Stark",
In
printName
}
console.log(printIronman());
// Tony Stark - ironman - NJ
console.log(printIronman());
// Tony Stark - ironman - NJ
js
Implementation
w.
Function.prototype.bind = function myBind(thisArg, ...args) {
js
// Return away the result generated by invoking the
function `fn`
return result;
w.
}
}
e
r vi
te
Note:
Rest of the premium content is added in the complete
In