[Frontend] Interview Questions

Prepare List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
How to hide element (visually hide)
CSS grid v.s. Flexbox v.s. Float
Accessibility
SEO optimization

Implement(HTML, CSS, Javascript):-baidu 1point3acres
Autocomplete-baidu 1point3acres
Modal
Progress bar
Star widget
Timer
Carousel
Masonry
Input Validator

Implement (Javascript):
Promise
Promise with limit
Promise.all
querySelector
EvenEmitter
Observable
Flat array
Given two identical DOM tree structures, A and B, and a node from A, find the corresponding node in B.


Implement (Util function)
Debounce
Throttle
Memoize
Retry

Really Good Resources

Web development

  1. 10 high level web-dev interview questions

Javascript

  1. this keyword and scope in JS
  2. Inheritance in JS
  3. A resource hub
  4. Event delegation, closure, and debouncing
  5. (By a Amazon Manager)Preparing for a Front-End Web Development Interview at Top Tech Companies
  6. Have to know

Execution Context and Closure

Lexical Scope.

A closure is basically when an inner function has access to variables outside of its scope.

Q: Write a function that will loop through a list of integers and print the index of each element after a 3 second delay

Question: How to properly use closures in loops? Quick answer: Use a function factory.
https://stackoverflow.com/questions/3572480/please-explain-the-use-of-javascript-closures-in-loops

Key Points:

  1. A closure captures the variable itself.
  2. Using a simple closure in a loop will end up with all closures sharing the same variable and that variable will contain the last value assigned to it in the loop
  3. What we want is an instance of that variable or at least a simple reference to the variable instead of the variable itself. Fortunately javascript already has a mechanism for passing a reference (for objects) or value (for strings and numbers): function arguments! When a function is called in javascript the arguments to that function is passed by reference if it is an object or by value if it is a string or number. This is enough to break variable sharing in closures.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
for (var i=0; i<10; i++) {
document.getElementById(i).onclick = function(){alert(i)}; // All elements when clicked will generate an alert box with the number 10.
}

for (var i=0; i<10; i++) {
document.getElementById(i).onclick =
(function(x){ /* we use this function expression simply as a factory
to return the function we really want to use: */

/* we want to return a function reference
so we write a function expression*/
return function(){
alert(x); /* x here refers to the argument of the factory function
captured by the 'inner' closure */
}

/* The brace operators (..) evaluates an expression, in this case this
function expression which yields a function reference. */

})(i) /* The function reference generated is then immediately called()
where the variable i is passed */
}
1
2
3
4
5
6
const loopThrough = (n) => {
for (let i = 0; i < n; i++) {
setTimeout(
() => {() => alert(num)},3000)
}
}

Event Delegation and bubbling

Add the event listener to the parent element, when the event bubbles up to the <ul> element, you check the event object’s target property to gain a reference tot he actual clicked node.

1
2
3
4
5
6
7
8
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
}
});

// Get the parent DIV, add click listener...
document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if (e.target && e.target.matches("a.classA")) {
console.log("Anchor element clicked!");
}
});

Object prototypes, constructors and mixins.

Composition and high order functions.

Type Coersion

JavaScript type coercion explained

Asynchronous calls

DOM

  • Select Node: document.querySelector()x
  • Traverse up-and-down: Node.parentNode(), Node.firstChild(), Node.lastChild(), Node.childNodes().
  • Traverse left and right: Node.previousSibling(), Node.nextSibling().

Create, copy, update nodes:

  • Create new node: document.createElement(), document.createTextNode()
  • Update text of node: node.textCotent = ..., node.innerHTML = ...

Insert node into DOM:

  • Add node as the last child: parentNode.appendChild()
  • Insert node before a sibling node under parent node: parentNode.insertBefore(newNode, nextSibling);
  • Replacing an existing node: parentNode.replaceChild(newNode, oldNode)

Remove node from DOM:

  • Remove child node: node.removeChild(childNode)
  • Remove node: node.remove()

Modify element attributes:

  • element.hasAttribute('href')
  • element.getAttribute('href')
  • element.removeAttribute('href')
  • element.setAttribute('href')

Modify element classes:

  • element.className: Return a set of class names
  • element.classList.add('newClass'): Add one / more classes
  • element.classList.toggle('class'): toggle class
  • element.classList.replace('old', 'new'): replace old class with new class
  • element.classList.remove('active'): remove class

Set style

  • div.style.height = '200%'