INTERVIEW QUESTIONS For Frontend Developer
INTERVIEW QUESTIONS For Frontend Developer
The primary responsibility of the rendering engine is to highlight the requested page on the browser’s
screen. Rendering engines can show XML and HTML images and documents. If you’re utilising additional
plugins, the engines can also exhibit various documents like PDF.
Receives the requested document: The contents of the requested document is obtained by the
rendering engine from HTML’s networking layer.
Construct the DOM tree: Parsed the HTML to the parsed tree and then set up the DOM tree, making
use of it.
Construct the CSSOM: CSSOM stands for CSS Object Model. Post the construction of the DOM tree, it
identifies a link tag in the head section, which references the external style.css CSS style sheet. So, it
parsed the CSS file in CSSOM tree, something which the Browser can comprehend as the DOM tree.
Construct the Render tree: Utilise the HTML DOM tree coupled with the styling data of the CSSOM
tree to set up a render tree. Render tree is the graphical depiction of the HTML, with the
corresponding CSS. This tree enables painting the contents in their right order. Every node in the
Render Tree is regarded as a renderer. The Render tree looks like this:
Layout: When the renderer is developed and incorporated into the tree, it does not have a size or
position. Computing these values is defined as layout. We use the coordinates system to position the
element, such as the position of the root renderer is 0,0. The layout continues recursively via a part of
the entire renderer hierarchy, calculating geometric info for every renderer that needs it. Beginning
the layout process implies allowing every node the exact coordinates where it should show up on
the screen.
Painting of the Render Tree: The renderer tree is traversed in this stage and the renderer’s paint()
method is hailed to exhibit the content on the screen. For good UX, the rendering engine will aim to
exhibit the contents on the screen as soon as possible. It will not stand by until all the HTML is parsed
to develop and layout the render tree.
From most other programming languages, Inheritance in JavaScript is different. JavaScript's object system is
prototype-based, not class-based. Objects in JavaScript are just a set of value pairs and a name (key). Talking
about inheritance, JavaScript just has one construct: objects. Each object has a private property that
includes a link to another object named its prototype.
While creating a complicated front-end application with tons of non-code static possessions, for instance,
CSS, fonts, images, etc, then, of course, you should make use of Webpack since it has a lot of amazing
benefits.
If you have a small application that doesn't have a lot of static resources and you only have to create one
file of JavaScript to help the customers, then Webpack should be more overhead than needed.
What is hoisting
Prior to executing the code, the interpreter appears to relocate the declarations of functions, variables, and
classes to the top of their scope using a process known as Hoisting in JavaScript. Functions can be securely
utilised in code before they have been declared thanks to hoisting. Variable and class declarations are
likewise hoisted, allowing them to be referenced prior to declaration. It should be noted that doing so can
result in unforeseen mistakes and is not recommended. There are usually two types of Hoisting:
Function Hoisting: Hoisting has the advantage of allowing you to use a function before declaring it in
your code as shown in the code snippet given below. Without function hoisting, we would have to
first write down the function display and only then can we call it.
display("Lion");
function display(inputString) {
console.log(inputString); // 'Lion' gets logged
}
Variable Hoisting: You can use a variable in code before it is defined and/or initialised because
hoisting works with variables as well. JavaScript, however, only hoists declarations, not initializations!
Even if the variable was initially initialised then defined, or declared and initialised on the same line,
initialization does not occur until the associated line of code is run. The variable has its default
initialization till that point in the execution is reached (undefined for a variable declared using var,
otherwise uninitialized). An example of variable hoisting is shown below:
console.log(x) // 'undefined' is logged from hoisted var declaration (instead of 7)
var x // Declaration of variable x
x = 7; // Initialization of variable x to a value 7
console.log(x); // 7 is logged post the line with initialization's execution.
Q14. What is Callback?
A callback is a plain JavaScript function passed to some method as an argument or option. It is a function that
is to be executed after another function has finished executing, hence the name ‘call back‘. In JavaScript,
functions are objects. Because of this, functions can take functions as arguments, and can be returned by other
functions.
The call() method calls a function with a given this value and arguments provided individually.
Syntax-
Syntax-
1fun.apply(thisArg, [argsArray])
Q12:
How would you use a closure to create a private counter?
Mid
JavaScript 179
Answer
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; }
}
}
Python 112
Q14:
What will be the output of the following code?
Mid
JavaScript 179
Problem
var y = 1;
if (function f() {}) {
y += typeof f;
}
console.log(y);
Answer
Above code would give output 1undefined. If condition statement evaluate using eval so eval(function f()
{}) which return function f() {} which is true so inside if statement code execute. typeof f return undefined
because if statement code execute at run time, so statement inside if condition evaluated at run time.
var k = 1;
if (1) {
eval(function foo() {});
k += typeof foo;
}
console.log(k);
Above code will also output 1undefined.
var k = 1;
if (1) {
function foo() {};
k += typeof foo;
}
console.log(k); // output 1function
Q15:
What will the following code output?
Mid
JavaScript 179
Problem
(function() {
var a = b = 5;
})();
console.log(b);
Answer
The code above will output 5 even though it seems as if the variable was declared within a function and can't
be accessed outside of it. This is because
var a = b = 5;
is interpreted the following way:
var a = b;
b = 5;
But b is not declared anywhere in the function with var so it is set equal to 5 in the global scope.
</script>
<script>
function checkAnagram(a, b) {
A closure is a function that has been bundled together (enclosed) with references to its surroundings (the
lexical environment). In other words, a closure allows an inner function to access the scope of an outside
function. Closures are formed every time a function is created in JavaScript, during function creation time.
An example of closures in Javascript is given below:
function subtractor(subtractingInteger) {
return function(a) {
return a - subtractingInteger;
};
}
var subtract2 = subtractor(2);
var subtract5 = subtractor(5);
console.log(subtract2(5)); // 3 is logged
console.log(subtract5(5)); // 0 is logged
In this example, we have developed a function subtractor(subtractingInteger) that takes a single parameter
subtractingInteger and returns a new function. Its return function accepts only one input, a, and returns the
difference of a and subtractingInteger. The function 'subtractor' is essentially a function factory. It creates
functions that have the ability to subtract a specified value from their arguments. The function factory
creates two new functions in the example above: one that subtracts 2 from its argument and one that
subtracts 5 from its arguments. Both subtract2 and subtract5 are closures. They have the same function
body definition, but they hold lexical surroundings that are distinct. subtractingInteger is 2 in subtract2's
lexical environment, but subtractingInteger is 5 in subtract5's lexical environment.
Event propagation is a technique that governs how events propagate or travel through the DOM tree to
reach their destination, as well as what happens to them once they arrive. Consider the following scenario:
you have been given a click event handler to a hyperlink (i.e. <a> element) that's nested inside a paragraph
(i.e. <p> element). The handler will now be executed if you click on that link. However, if you set the click
event handler to the paragraph containing the link instead of the link, the handler will be triggered
regardless of whether the link is clicked. Because events go up and down the DOM tree to reach their
target, they don't merely affect the target element that triggered the event. This is known as event
propagation.
When an event is fired on an element with parent elements, the above picture shows how the event travels
through the DOM tree at different stages of the event propagation. Event propagation in current browsers
is divided into two phases: capturing and bubbling.
The Capturing Phase: In the capturing phase, events propagate from the Window down through the
DOM tree to the target node. For example, if the user clicks a hyperlink, that click event would pass
through the <html> element, the <body> element, and the <p> element containing the link. Also if
any ancestor (i.e. parent, grandparent, etc.) of the target element and the target itself has a specially
registered capturing event listener for that type of event, those listeners are executed during this
phase.
The Bubbling Phase: From the target element up to the Window, the DOM tree visits all of the target
element's ancestors one by one. When a user hits a hyperlink, the click event passes via the <p>
element containing the link, the <body> element, the <html> element, and the document node, for
example. Additionally, if the target element or any of its ancestors have event handlers for that sort of
event, those handlers are run during this phase. By default, all event handlers in current browsers are
registered at the bubbling phase.
A number of Web API features now use asynchronous code for running, especially those that access or fetch
a resource from external devices, for instance, retrieving files from the network, accessing some database
and returning data to it, accessing a video stream from a webcam, or broadcasting the display to a VR
headset. There are two ways in which asynchronous coding can be done in JavaScript:
Async Callbacks: When invoking a function, async callbacks are functions that are passed as
arguments and begin executing code in the background. When the background code is finished, it
runs the callback function to notify you that the work is complete or that anything interesting has
occurred. Callbacks are a little out of date these days, but they're still utilised in a lot of older but still
popular APIs. The second parameter of the addEventListener() method is an example of an async
callback:
buton.addEventListener('click', () => {
alert('Button has been clicked!');
let paraElement = document.createElement('p');
paraElement.textContent = 'A new paragraph.';
document.body.appendChild(paraElement);
});
The first parameter specifies the type of event to be listened for, while the second specifies a callback
function to be called when the event occurs. When we give a callback function as an input to another
function, we are merely passing the function's reference; the callback function isn't immediately performed.
It is asynchronously "called back" (thus the name) somewhere within the containing function's body. When
the time comes, the contained function is in charge of calling the callback function.
Promises: Promises are a new async programming paradigm that you'll see in current Web APIs. The
get() API, which is essentially a newer, more efficient version of XMLHttpRequest, is a nice example.
Let's take a look at an example from our post Fetching data from the server:
fetch(items.json').then(function(res) {
return res.json();
}).then(function(json) {
let item = json;
initialise(item);
}).catch(function(e) {
console.log('Fetch error: ' + e.message);
});
Here, fetch() takes a single argument: the URL of a network resource we wish to fetch and a promise is
returned. A promise is an object that represents whether the async operation succeeded or failed. In a
sense, it reflects a transitional condition. In essence, it's the browser's way of saying, "I promise to respond
as quickly as I can," hence the name "promise."
Note: Pyramid of Doom, also known as Callback Hell, is an anti-pattern found in asynchronous computer
code. It is a slang phrase for a large number of interconnected "if" statements or functions. A few callbacks
appear harmless if you do not expect your application logic to become too sophisticated. However, as your
project's requirements grow, you will quickly find yourself with layers upon layers of nested callbacks. The
usage of callbacks makes writing and maintaining code more challenging. It also makes it more difficult to
identify the application's flow, which is a debugging roadblock, hence the problem's well-known nickname:
Callback Hell. An example of callback hell is given below:
fs.readdir(source, function (error, file) {
if (error) {
console.log(Problem occurred while finding file: ' + error)
} else {
file.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (error, value) {
if (error) {
console.log(Problem occurred while identifying file size: ' + error)
} else {
console.log(filename + ' : ' + value)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(error) {
if (error) console.log('Problem occurred while writing file: ' + error)
})
}.bind(this))
}
})
})
}
})
There are numerous things accountable for lowering page load time. Let us look at the three best ways to
reduce its loading time:
Image Optimization: It is always advised to scale your videos and pictures before uploading them to a
page.
Browser Cache: The utilization of cache will boost speed for pages that you have visited already.
Optimize and compress content: Compressing the content of a website decreases the load time of a
page to a great extent.
StyleSheet Reference on Top: Setting stylesheet reference to the header of a doc allows your page to
load quickly.
Generally, the function name is defined when we define the function itself, in normal user-defined
functions, but in the case of an anonymous function, the function name is not defined. Here we make use of
an assignment operator and variable to stow the function as an object, then utilizing that variable, we will
be capable to invoke the function itself.
Example:
22. What do you know about the CSS image sprites and why it is utilized?
CSS image sprites assist to render numerous images in a single line image. In a nutshell, the CSS sprites
merge numerous photos into a single large image. If a web page comprises different images, then it would
raise its loading time as for every image the browser has to send a distinct HTTP request, but with the help
of sprites, we have a single image to request.
The consumption of resources can be reduced by the pages by enhancing the server response.
Utilize JavaScript and External CSS instead of internal or in-line.
Utilize the framework to ensure the front-end becomes more responsive to different devices.
Open-source libraries can be used to manage the browser-specific styling issue.
Make use of progressive loading like Lazy Loading to enhance the rendering of heavy elements, like
videos and images.
Connect the style sheet in the header and script at the top of the HTML's body tag.
Utilize browser storage to keep user-specific private data.
Here, value and type are the attributes of HTML, but when the statement is read by the browser and parses
this code it will make a DOM with different properties, like accept, autofocus, accessKey, baseURI, checked,
childElementCount, align, alt, childNodes, children, classList, className, attributes, and clientHeight.
CSS splits the page into grids and utilizes those grids to handle the HTML content. Utilizing the Grids, CSS
can stack and highlight various elements in different parts of the grids.
DOM stands for Document Object Model. The DOM represents an HTML document with a logical tree
structure. Each branch of the tree ends in a node, and each node contains objects.
React keeps a lightweight representation of the real DOM in the memory, and that is known as the virtual
DOM. When the state of an object changes, the virtual DOM changes only that object in the real DOM, rather
than updating all the objects.
Easy creation of dynamic applications: React makes it easier to create dynamic web applications because it
provides less coding and provides more functionality, whereas, with JavaScript applications, code tends to get
complex very quickly.
Improved performance: React uses virtual DOM, which makes web applications perform faster. Virtual DOM
compares its previous state and updates only those components in the real DOM, whose states have changed,
rather than updating all the components — like conventional web applications.
Reusable components: Components are the building blocks of any React application, and a single app usually
consists of multiple components. These components have their own logic and controls, and they can be reused
through the application, which, in turn, dramatically reduces the development time of an application.
Unidirectional data flow: React follows a unidirectional data flow. This means that when designing a React app,
we often nest child components within parent components. And since the data flows in a single direction, it
becomes easier to debug errors and know where the problem occurs in an application at the moment.
Dedicated tools for easy debugging: Facebook has released a chrome extension that we can use to debug
React applications. This makes the process of debugging React to web applications faster and easier.
These are the few instances where ES6 syntax has changed from ES5 syntax:
require vs import
10. What are synthetic events in React?
Synthetic events combine the response of different browser's native events into one API, ensuring
that the events are consistent across different browsers.
The application is consistent regardless of the browser it is running in. Here, preventDefault is a
synthetic event.
It also helps to determine which components need to be re-rendered instead of re-rendering all
the components every time. Therefore, it increases performance, as only the updated
components are re-rendered
It is unnecessary to bind ‘this’ inside the constructor when using an arrow function. This prevents
bugs caused by the use of ‘this’ in React callbacks.
Components are the building blocks of any React application, and a single app usually consists of multiple
components. A component is essentially a piece of the user interface. It splits the user interface into
independent, reusable parts that can be processed separately.
function Greeting(props) {
Class Components: These types of components can hold and manage their own state and have a
separate render method to return JSX on the screen. They are also called Stateful components as
they can have a state.
render() {
}
27. What is a higher-order component in React?
A higher-order component acts as a container for other components. This helps to keep components simple
and enables re-usability. They are generally used when multiple components have to use a common logic.
componentDidMount(): Is executed when the component gets rendered and placed on the DOM.
So far, if you have any doubts about the above React interview questions and answers, please ask your
questions in the section below.
Redux is an open-source, JavaScript library used to manage the application state. React uses Redux to build the
user interface. It is a predictable state container for JavaScript applications and is used for the entire
application’s state management.
Reducer: Specifies how the application's state changes in response to actions sent to the store.
33. What is the Flux?
Flux is the application architecture that Facebook uses for building web applications. It is a
method of handling complex data inside a client-side application and manages how data flows in a
React application.
There is a single source of data (the store) and triggering certain actions is the only way way to
update them.The actions call the dispatcher, and then the store is triggered and updated with
their own data accordingly.
When a dispatch has been triggered, and the store updates, it will emit a change event that the
views can rerender accordingly.
32. What is the most challenging work you have ever done as a front-end developer?
There are different reasons why a JavaScript developer should consider using TypeScript. Some of them
include:
Using new features of ECMAScript: TypeScript supports new ECMAScript standards and transpile
them to ECMAScript targets of your choice. So, you can use features of ES2015 and beyond.
Static Typing: JavaScript is dynamically typed and does not know what type a variable is until it is
actually instantiated at run-time. TypeScript adds type support to JavaScript.
Type Inference: TypeScript makes typing a bit easier and a lot less explicit by the usage of type
inference. Even if you don’t explicitly type the types, they are still there to save you from doing
something which otherwise would result in a run-time error.
Better IDE Support: The development experience with TypeScript is a great improvement over
JavaScript. There is a wide range of IDEs that have excellent support for TypeScript, like Visual
Studio & VS code, Atom, Sublime, and IntelliJ/WebStorm.
Strict Null Checking: Errors, like cannot read property ‘x’ of undefined, is common in JavaScript
programming. You can avoid most of these kinds of errors since one cannot use a variable that is not
known to the TypeScript compiler.
Cross-Platform: The TypeScript compiler can be installed on any Operating System such as Windows,
MacOS, and Linux.
Object-Oriented Language: TypeScript provides features like Classes, Interfaces, and Modules. Thus,
it can write object-oriented code for client-side as well as server-side development.
Static Type-Checking: TypeScript uses static typing and helps type checking at compile time. Thus, you
can find errors while writing the code without running the script.
Optional Static Typing: TypeScript also allows optional static typing in case you are using the dynamic
typing of JavaScript.
DOM Manipulation: You can use TypeScript to manipulate the DOM for adding or removing
elements.
ES 6 Features: TypeScript includes most features of planned ECMAScript 2015 (ES 6, 7) such as class,
interface, Arrow functions, etc.
If we run the TypeScript application in the browser, a compilation step is required to transform
TypeScript into JavaScript.
Web developers are using JavaScript for decades and TypeScript doesn’t bring anything new.
The interface is a structure that defines the contract in your application. It defines the syntax for classes to
follow. It contains only the declaration of the members and it is the responsibility of the deriving class to
define the members. The TypeScript compiler uses interface for type-checking and checks whether the object
has a specific structure or not.
Syntax:
1interface interface_name {
2// variables' declaration
3// methods' declaration
4}
Q19. What are Classes in TypeScript? List out some of the features.
TypeScript introduced classes so that they can avail the benefits of object-oriented techniques like
encapsulation and abstraction. The class in TypeScript is compiled to plain JavaScript functions by the
TypeScript compiler to work across platforms and browsers.
Constructor
Properties
Methods
Example:
1class Employee {
2empID: number;
3empName: string;
4
5constructor(ID: number, name: string) {
6this.empName = name;
7this.empID = ID;
8}
9
10getSalary() : number {
11return 40000;
12}
13}
14}
Some of the features of a class are:
Inheritance
Encapsulation
Polymorphism
Abstraction
Q26. Explain Decorators in TypeScript.
A Decorator is a special kind of declaration that can be applied to classes, methods, accessor,
property, or parameter. Decorators are functions that are prefixed @expression symbol, where
expression must evaluate to a function that will be called at runtime with information about the
decorated declaration.
TypeScript Decorators serves the purpose of adding both annotations and metadata to the existing
code in a declarative way. To enable experimental support for decorators,you need to enable the
experimentalDecorators compiler option either on the command line or in our tsconfig.json:
Command Line
$tsc --target ES5 --experimentalDecorators
tsconfig.json
1{
2"compilerOptions": {
3"target": "ES5",
4"experimentalDecorators": true
5}
6}
Q25. Does TypeScript support function overloading?
Yes, TypeScript supports function overloading. But the implementation is odd. So, when you overload
in TypeScript you only have one implementation with multiple signatures.
For example:
1class Customer {
2name: string;
3Id: number;
4add(Id: number);
5add(name:string);
6add(value: any) {
7if (value && typeof value == "number") {
8//Do something
9}
10if (value && typeof value == "string") {
11//Do Something
12}
13}
The first signature has one parameter of type number whereas the second signature has a parameter
of type string. The third function contains the actual implementation and has a parameter of type any.
The implementation then checks for the type of the supplied parameter and executes a different
piece of code based on the supplier parameter type.
Q24. What is namespace in Typescript and how to declare it?
Namespace groups functionalities logically. These maintain the legacy code of typescript internally. It
encapsulates the features and objects that share certain relationships. A namespace is also known as
internal modules. A namespace can also include interfaces, classes, functions, and variables to
support a group of related functionalities.
Syntax:
1namespace <namespace_name> {
2export interface I1 { }
3export class c1{ }
4}
Q22. What are modules in TypeScript?
A module is a powerful way of creating a group of related variables, functions, classes, and interfaces,
etc. It can be executed within its own scope, but not in the global scope. Basically, you cannot access
the variables, functions, classes, and interfaces declared in a module outside the module directly.
A module can be created by using the export keyword and can be used in other modules by using
the import keyword.
Example:
1module module_name{
2class xyz{
3export sum(x, y){
4return x+y;
5}
6}
There are times when you want to store a value in a variable but don’t know the type of that variable in
advance. For example, the value is coming from an API call or the user input. The ‘any’ type allows you to
assign a value of any type to the variable of type any.
The void indicates the absence of type on a variable. It acts as the opposite type to any. It is especially useful
in functions that don’t return a value.
If a variable is of type void, you can only assign the null or undefined values to that variable.
8. How to create objects in TypeScript?
Objects are dictionary-like collections of keys and values. The keys have to be unique. They are similar to
arrays and are also sometimes called associative arrays. However, an array uses numbers to index the
values, whereas an object allows you to use any other type as the key.
In TypeScript, an Object type refers to any value with properties. It can be defined by simply listing the
properties and their types. For example,
An object type can have zero or more optional properties by adding a ‘?’ after the property name.
In the example above, because the property ‘z’ is marked as optional, the compiler won’t complain if we
don’t provide it during the initialization.
Enums allow us to create named constants. It is a simple way to give more friendly names to numeric
constant values. An enum is defined by the keyword enum, followed by its name and the members.
Consider the following example that defines an enum Team with four values in it.
enum Team {
Alpha,
Beta,
Gamma,
Delta
}
let t: Team = Team.Delta;
By default, the enums start the numbering at 0. You can override the default numbering by explicitly
assigning the values to its members.
TypeScript also lets you create enums with string values as follows:
enum Author {
Anders = "Anders",
Hejlsberg = "Hejlsberg"
};
A rest parameter allows a function to accept an indefinite number of arguments as an array. It is denoted by
the ‘…’ syntax and indicates that the function can accept one or more arguments.
In contrast, the rest arguments allow a function caller to provide a variable number of arguments from an
array. Consider the following example.
first.push(...second);
console.log(first); // [1, 2, 3, 4, 5, 6]
A function can mark one or more of its parameters as optional by suffixing its name with ‘?’. In the example
below, the parameter greeting is marked optional.
console.log(`${greeting}, ${name}`);
}
Optional chaining allows you to access properties and call methods on them in a chain-like fashion. You can
do this using the ‘?.’ operator.
TypeScript immediately stops running some expression if it runs into a ‘null’ or ‘undefined’ value and
returns ‘undefined’ for the entire expression chain.
let x = foo?.bar.baz();
Function overloading allows us to define multiple functions with the same name, as long as their number of
parameters or the types of parameters are different.
The following example defines two overloads for the function buildDate. The first overload takes a number
as a parameter, whereas the second takes three numbers as parameters. These are called overload
signatures.
The body of the function also called an implementation signature, follows the overload signatures. You can’t
call this signature directly, as it’s not visible from the outside. It should be compatible with the overload
signatures.
const d1 = buildDate(87654321);
const d2 = buildDate(2, 2, 2);