Sunday, March 10, 2019

Javascript Interview Questions and Answers




1.) What is difference between splice and slice in Array




2.) Creation and initializing Prototype
var Human = function() {
this.canWalk = true;
this.canSpeak = true; //
};
Person.prototype.greet = function() {
if (this.canSpeak) { // checks whether this prototype has instance of speak
this.name = "Steve"
console.log('Hi, I am ' + this.name);
} else{
console.log('Sorry i can not speak');
}
};
The prototype can be instantiated like this
obj = Object.create(Person.prototype);
ob.greet();
We can pass value for the constructor and make the boolean true and false based on the requirement.
Detailed Explanation
var Human = function() {
this.canSpeak = true;
};
// Basic greet function which will greet based on the canSpeak flag
Human.prototype.greet = function() {
if (this.canSpeak) {
console.log('Hi, I am ' + this.name);
}
};
var Student = function(name, title) {
Human.call(this); // Instantiating the Human object and getting the memebers of the class
this.name = name; // inheriting the name from the human class
this.title = title; // getting the title from the called function
};
Student.prototype = Object.create(Human.prototype);
Student.prototype.constructor = Student;
Student.prototype.greet = function() {
if (this.canSpeak) {
console.log('Hi, I am ' + this.name + ', the ' + this.title);
}

};
var Customer = function(name) {
Human.call(this); // inheriting from the base class
this.name = name;
};
Customer.prototype = Object.create(Human.prototype); // creating the object
Customer.prototype.constructor = Customer;
var bill = new Student('Billy', 'Teacher');
var carter = new Customer('Carter');
var andy = new Student('Andy', 'Bill');
var virat = new Customer('Virat');
bill.greet();
// Hi, I am Bob, the Teacher
carter.greet();
// Hi, I am Carter
andy.greet();
// Hi, I am Andy, the Bill
virat.greet();


3.) Insert an item into an array at a specific index
Simple item insertion can be done with Array.prototype.splice method:
arr.splice(index, 0, item);
More advanced variant with multiple arguments and chaining support:
/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
this.splice.apply(this, [index, 0].concat(
Array.prototype.slice.call(arguments, 1)));
return this;
};
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6); // ["b", "X", "Y", "Z", "c"]

3.) Inheritance
Section 1: Standard function prototype
Start by defining a Foo function that we'll use as a constructor.
function Foo (){}
By editing Foo.prototype , we can define properties and methods that will be shared by all instances of Foo .
Foo.prototype.bar = function() {
return 'I am bar';
};
We can then create an instance using the new keyword, and call the method.
var foo = new Foo();
console.log(foo.bar()); // logs `I am bar`
Section 2: Difference between Object.key and
Object.prototype.key
Unlike in languages like Python, static properties of the constructor function are not inherited to instances.
Instances only inherit from their prototype, which inherits from the parent type's prototype. Static properties are
never inherited.
function Foo() {};
Foo.style = 'bold';
var foo = new Foo();
console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined
Foo.prototype.style = 'italic';
console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'
Section 3: Prototypal inheritance
Suppose we have a plain object called prototype :
var prototype = { foo: 'foo', bar: function () { return this.foo; } };
Now we want another object called obj that inherits from prototype , which is the same as saying that prototype is
the prototype of obj
var obj = Object.create(prototype);
Now all the properties and methods from prototype will be available to obj
console.log(obj.foo);
console.log(obj.bar());
Console output
"foo"
"foo"
Prototypal inheritance is made through object references internally and objects are completely mutable. This
means any change you make on a prototype will immediately affect every other object that prototype is prototype
of.
prototype.foo = "bar";
console.log(obj.foo);
Console output
"bar"
Object.prototype is the prototype of every object, so it's strongly recommended you don't mess with it, especially
if you use any third party library, but we can play with it a little bit.
Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);
Console output
"foo"
"foo"
Fun fact I've used the browser console to make these examples and broken this page by adding that
breakingLibraries property.
Section 4: Pseudo-classical inheritance
It's an emulation of classical inheritance using prototypical inheritance which shows how powerful prototypes are. It
was made to make the language more attractive to programmers coming from other languages.
Version < 6
IMPORTANT NOTE: Since ES6 it doesn't make sense to use pseudo-classical inheritance since the language
simulates conventional classes. If you're not using ES6, you should. If you still want to use the classical inheritance
pattern and you're in a ECMAScript 5 or lower environment, then pseudo-classical is your best bet.
A "class" is just a function that is made to be called with the new operand and it's used as a constructor.
function Foo(id, name) {
this.id = id;
this.name = name;
}
var foo = new Foo(1, 'foo');
GoalKicker.com – JavaScript® Notes for Professionals 208
console.log(foo.id);
Console output
1
foo is an instance of Foo. The JavaScript coding convention says if a function begins with a capital letter case it can
be called as a constructor (with the new operand).
To add properties or methods to the "class" you have to add them to its prototype, which can be found in the
prototype property of the constructor.
Foo.prototype.bar = 'bar';
console.log(foo.bar);
Console output
bar
In fact what Foo is doing as a "constructor" is just creating objects with Foo.prototype as it's prototype.
You can find a reference to its constructor on every object
console.log(foo.constructor);
function Foo(id, name) { ...
console.log({ }.constructor);
function Object() { [native code] }
And also check if an object is an instance of a given class with the instanceof operator
console.log(foo instanceof Foo);
true
console.log(foo instanceof Object);
true
Section 5: Setting an Object's prototype
Version ≥ 5
With ES5+, the Object.create function can be used to create an Object with any other Object as it's prototype.
const anyObj = {
hello() {
console.log(`this.foo is ${this.foo}`);
},
};
let objWithProto = Object.create(anyObj);
objWithProto.foo = 'bar';
objWithProto.hello(); // "this.foo is bar"
To explicitly create an Object without a prototype, use null as the prototype. This means the Object will not inherit
from Object.prototype either and is useful for Objects used for existence checking dictionaries, e.g.
let objInheritingObject = {};
let objInheritingNull = Object.create(null);
'toString' in objInheritingObject; // true
'toString' in objInheritingNull ; // false
Version ≥ 6
From ES6, the prototype of an existing Object can be changed using Object.setPrototypeOf , for example
let obj = Object.create({foo: 'foo'});
obj = Object.setPrototypeOf(obj, {bar: 'bar'});
obj.foo; // undefined
obj.bar; // "bar"
This can be done almost anywhere, including on a this object or in a constructor.
Note: This process is very slow in current browsers and should be used sparingly, try to create the Object with the
desired prototype instead.
Version < 5
Before ES5, the only way to create an Object with a manually defined prototype was to construct it with new , for
example
var proto = {fizz: 'buzz'};
function ConstructMyObj() {}
ConstructMyObj.prototype = proto;
var objWithProto = new ConstructMyObj();
objWithProto.fizz; // "buzz"
This behaviour is close enough to Object.create that it is possible to write a polyfill.

4.) Callbacks
Section 1: Simple Callback Usage Examples
Callbacks offer a way to extend the functionality of a function (or method) without changing its code. This approach
is often used in modules (libraries / plugins), the code of which is not supposed to be changed.
Suppose we have written the following function, calculating the sum of a given array of values:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
}
Now suppose that we want to do something with each value of the array, e.g. display it using alert() . We could
make the appropriate changes in the code of foo , like this:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
alert(array[i]);
sum += array[i];
}
return sum;
}
But what if we decide to use console.log instead of alert() ? Obviously changing the code of foo , whenever we
decide to do something else with each value, is not a good idea. It is much better to have the option to change our
mind without changing the code of foo . That's exactly the use case for callbacks. We only have to slightly change
foo 's signature and body:
function foo(array, callback) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
callback(array[i]);
sum += array[i];
}
return sum;
}
And now we are able to change the behaviour of foo just by changing its parameters:
var array = [];
foo(array, alert);
foo(array, function (x) {
console.log(x);
});
Examples with Asynchronous Functions
In jQuery, the $.getJSON() method to fetch JSON data is asynchronous. Therefore, passing code in a callback
makes sure that the code is called after the JSON is fetched.
$.getJSON() syntax:
$.getJSON( url, dataObject, successCallback );
Example of $.getJSON() code:
$.getJSON("foo.json", {}, function(data) {
// data handling code
});
The following would not work, because the data-handling code would likely be called before the data is actually
received, because the $.getJSON function takes an unspecified length of time and does not hold up the call stack as
it waits for the JSON.
$.getJSON("foo.json", {});
// data handling code
Another example of an asynchronous function is jQuery's animate() function. Because it takes a specified time to
run the animation, sometimes it is desirable to run some code directly following the animation.
.animate() syntax:
jQueryElement.animate( properties, duration, callback );
For example, to create a fading-out animation after which the element completely disappears, the following code
can be run. Note the use of the callback.
elem.animate( { opacity: 0 }, 5000, function() {
elem.hide();
} );
This allows the element to be hidden right after the function has finished execution. This differs from:
elem.animate( { opacity: 0 }, 5000 );
elem.hide();
because the latter does not wait for animate() (an asynchronous function) to complete, and therefore the element
is hidden right away, producing an undesirable effect.


Section 2: Continuation (synchronous and asynchronous)
Callbacks can be used to provide code to be executed after a method has completed:
/**
* @arg {Function} then continuation callback
*/
function doSomething(then) {
console.log('Doing something');
then();
}
// Do something, then execute callback to log 'done'
doSomething(function () {
console.log('Done');
});
GoalKicker.com – JavaScript® Notes for Professionals 215
console.log('Doing something else');
// Outputs:
// "Doing something"
// "Done"
// "Doing something else"
The doSomething() method above executes synchronously with the callback - execution blocks until doSomething()
returns, ensuring that the callback is executed before the interpreter moves on.
Callbacks can also be used to execute code asynchronously:
doSomethingAsync(then) {
setTimeout(then, 1000);
console.log('Doing something asynchronously');
}
doSomethingAsync(function() {
console.log('Done');
});
console.log('Doing something else');
// Outputs:
// "Doing something asynchronously"
// "Doing something else"
// "Done"
The then callbacks are considered continuations of the doSomething() methods. Providing a callback as the last
instruction in a function is called a tail-call, which is optimized by ES2015 interpreters.
Section 3: What is a callback?
This is a normal function call:
console.log("Hello World!");
When you call a normal function, it does its job and then returns control back to the caller.
However, sometimes a function needs to return control back to the caller in order to do its job:
[1,2,3].map(function double(x) {
return 2 * x;
});
In the above example, the function double is a callback for the function map because:
The function double is given to the function map by the caller. 1.
The function map needs to call the function double zero or more times in order to do its job. 2.
Thus, the function map is essentially returning control back to the caller every time it calls the function double .
Hence, the name “callback”.
Functions may accept more than one callback:
promise.then(function onFulfilled(value) {
console.log("Fulfilled with value " + value);
}, function onRejected(reason) {
console.log("Rejected with reason " + reason);
});
Here then function then accepts two callback functions, onFulfilled and onRejected . Furthermore, only one of
these two callback functions is actually called.
What's more interesting is that the function then returns before either of the callbacks are called. Hence, a callback
function may be called even after the original function has returned.
Section 4: Callbacks and `this`
Often when using a callback you want access to a specific context.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg); // <= will fail because "this" is undefined
});
}
var s = new SomeClass("hello", someElement);
Solutions
Use bind
bind effectively generates a new function that sets this to whatever was passed to bind then calls the
original function.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg);
}.bind(this)); // <=- bind the function to `this`
}
Use arrow functions
Arrow functions automatically bind the current this context.
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click',() => { // <=- arrow function binds `this`
console.log(this.msg);
});
}
Often you'd like to call a member function, ideally passing any arguments that were passed to the event on to the
function.
Solutions:
Use bind
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', this.handleClick.bind(this));
}
SomeClass.prototype.handleClick = function(event) {
console.log(event.type, this.msg);
};
Use arrow functions and the rest operator
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', (...a) => this.handleClick(...a));
}
SomeClass.prototype.handleClick = function(event) {
console.log(event.type, this.msg);
};
For DOM event listeners in particular you can implement the EventListener interface
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', this);
}
SomeClass.prototype.handleEvent = function(event) {
var fn = this[event.type];
if (fn) {
fn.apply(this, arguments);
}
};
SomeClass.prototype.click = function(event) {
console.log(this.msg);
};
Section 5: Callback using Arrow function
Using arrow function as callback function can reduce lines of code.
The default syntax for arrow function is
() => {}
This can be used as callbacks
For example if we want to print all elements in an array [1,2,3,4,5]
without arrow function, the code will look like this
[1,2,3,4,5].forEach(function(x){
console.log(x);
}
With arrow function, it can be reduced to
[1,2,3,4,5].forEach(x => console.log(x));
Here the callback function function(x){console.log(x)} is reduced to x=>console.log(x)
Section 6: Error handling and control-flow branching
Callbacks are often used to provide error handling. This is a form of control flow branching, where some
instructions are executed only when an error occurs:
const expected = true;
function compare(actual, success, failure) {
if (actual === expected) {
success();
} else {
failure();
}
}
function onSuccess() {
console.log('Value was expected');
}
function onFailure() {
console.log('Value was unexpected/exceptional');
}
compare(true, onSuccess, onFailure);
compare(false, onSuccess, onFailure);
// Outputs:
// "Value was expected"
// "Value was unexpected/exceptional"
Code execution in compare() above has two possible branches: success when the expected and actual values are
the same, and error when they are different. This is especially useful when control flow should branch after some
asynchronous instruction:
function compareAsync(actual, success, failure) {
setTimeout(function () {
compare(actual, success, failure)
}, 1000);
}
compareAsync(true, onSuccess, onFailure);
compareAsync(false, onSuccess, onFailure);
console.log('Doing something else');
// Outputs:
// "Doing something else"
// "Value was expected"
// "Value was unexpected/exceptional"
It should be noted, multiple callbacks do not have to be mutually exclusive – both methods could be called.
Similarly, the compare() could be written with callbacks that are optional (by using a noop as the default value - see
Null Object pattern).

5.) Promises:
Section 1: Introduction
A Promise object represents an operation which has produced or will eventually produce a value. Promises provide a
robust way to wrap the (possibly pending) result of asynchronous work, mitigating the problem of deeply nested
callbacks (known as "callback hell").
States and control flow
A promise can be in one of three states:
pending — The underlying operation has not yet completed, and the promise is pending fulfillment.
fulfilled — The operation has finished, and the promise is fulfilled with a value. This is analogous to returning a
value from a synchronous function.
rejected — An error has occurred during the operation, and the promise is rejected with a reason. This is
analogous to throwing an error in a synchronous function.
A promise is said to be settled (or resolved) when it is either fulfilled or rejected. Once a promise is settled, it
becomes immutable, and its state cannot change. The then and catch methods of a promise can be used to attach
callbacks that execute when it is settled. These callbacks are invoked with the fulfillment value and rejection reason,
respectively.
Example
const promise = new Promise((resolve, reject) => {
// Perform some work (possibly asynchronous)
// ...
if (/* Work has successfully finished and produced "value" */) {
resolve(value);
} else {
// Something went wrong because of "reason"
// The reason is traditionally an Error object, although
// this is not required or enforced.
let reason = new Error(message);
reject(reason);
// Throwing an error also rejects the promise.
throw reason;
}
});
The then and catch methods can be used to attach fulfillment and rejection callbacks:
promise.then(value => {
// Work has completed successfully,
// promise has been fulfilled with "value"
}).catch(reason => {
// Something went wrong,
// promise has been rejected with "reason"
});
Note: Calling promise.then(...) and promise.catch(...) on the same promise might result in an Uncaught
exception in Promise if an error occurs, either while executing the promise or inside one of the callbacks, so the
preferred way would be to attach the next listener on the promise returned by the previous then / catch .
Alternatively, both callbacks can be attached in a single call to then :
promise.then(onFulfilled, onRejected);
Attaching callbacks to a promise that has already been settled will immediately place them in the microtask queue,
and they will be invoked "as soon as possible" (i.e. immediately after the currently executing script). It is not
necessary to check the state of the promise before attaching callbacks, unlike with many other event-emitting
implementations.
Live demo
Section 2: Promise chaining
The then method of a promise returns a new promise.
const promise = new Promise(resolve => setTimeout(resolve, 5000));
promise
// 5 seconds later
.then(() => 2)
// returning a value from a then callback will cause
// the new promise to resolve with this value
.then(value => { /* value === 2 */ });
Returning a Promise from a then callback will append it to the promise chain.
function wait(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
const p = wait(5000).then(() => wait(4000)).then(() => wait(1000));
p.then(() => { /* 10 seconds have passed */ });
A catch allows a rejected promise to recover, similar to how catch in a try / catch statement works. Any chained
then after a catch will execute its resolve handler using the value resolved from the catch .
const p = new Promise(resolve => {throw 'oh no'});
p.catch(() => 'oh yes').then(console.log.bind(console)); // outputs "oh yes"
If there are no catch or reject handlers in the middle of the chain, a catch at the end will capture any rejection in
the chain:
p.catch(() => Promise.reject('oh yes'))
.then(console.log.bind(console)) // won't be called
.catch(console.error.bind(console)); // outputs "oh yes"
On certain occasions, you may want to "branch" the execution of the functions. You can do it by returning different
promises from a function depending on the condition. Later in the code, you can merge all of these branches into
one to call other functions on them and/or to handle all errors in one place.
promise
.then(result => {
if (result.condition) {
return handlerFn1()
.then(handlerFn2);
} else if (result.condition2) {
return handlerFn3()
.then(handlerFn4);
} else {
throw new Error("Invalid result");
}
})
.then(handlerFn5)
.catch(err => {
console.error(err);
});
Thus, the execution order of the functions looks like:
promise --> handlerFn1 -> handlerFn2 --> handlerFn5 ~~> .catch()
| ^V |-> handlerFn3 -> handlerFn4 -^
The single catch will get the error on whichever branch it may occur.
Section 3: Waiting for multiple concurrent promises
The Promise.all() static method accepts an iterable (e.g. an Array ) of promises and returns a new promise, which
resolves when all promises in the iterable have resolved, or rejects if at least one of the promises in the iterable
have rejected.
// wait "millis" ms, then resolve with "value"
function resolve(value, milliseconds) {
return new Promise(resolve => setTimeout(() => resolve(value), milliseconds));
}
// wait "millis" ms, then reject with "reason"
function reject(reason, milliseconds) {
return new Promise((_, reject) => setTimeout(() => reject(reason), milliseconds));
}
Promise.all([
resolve(1, 5000),
resolve(2, 6000),
resolve(3, 7000)
]).then(values => console.log(values)); // outputs "[1, 2, 3]" after 7 seconds.
Promise.all([
resolve(1, 5000),
reject('Error!', 6000),
resolve(2, 7000)
]).then(values => console.log(values)) // does not output anything
.catch(reason => console.log(reason)); // outputs "Error!" after 6 seconds.
Non-promise values in the iterable are "promisified".
Promise.all([
resolve(1, 5000),
resolve(2, 6000),
{ hello: 3 }
])
.then(values => console.log(values)); // outputs "[1, 2, { hello: 3 }]" after 6 seconds
Destructuring assignment can help to retrieve results from multiple promises.
Promise.all([
resolve(1, 5000),
resolve(2, 6000),
resolve(3, 7000)
])
.then(([result1, result2, result3]) => {
console.log(result1);
console.log(result2);
console.log(result3);
});

1.) What is difference between var and  let keyword
The var keyword creates a function-scope variable.
The let keyword creates a block-scope variable.
The const keyword creates a block-scope variable that cannot be reassigned.
A bare declaration creates a global variable.
var a = 'foo'; // Function-scope
let b = 'foo'; // Block-scope
const c = 'foo'; // Block-scope & immutable reference
Keep in mind that you can't declare constants without initializing them at the same time.
const foo; // "Uncaught SyntaxError: Missing initializer in const declaration"

No comments:

Post a Comment

Top DataStructures Problem from Medium-2

  Array: Find a pair with the given sum in an array Maximum Sum Subarray Problem (Kadane’s Algorithm) Longest Increasing Subsequence Problem...