JavaScript Questions Flashcards
Explain event delegation
Explanation: Setting an event listener on a parent element and having events that happen on a child element bubble up to the parent.
Use: When you want some code to run when the user interacts with any one of a large number of child elements.
Example:
<div>
<div></div>
</div>
<script> container.addEventListener('click', (event) => (event.target.style.backgroundColor = bgChange())); </script>
Event Delegation is basically a pattern to handle events efficiently. Instead of adding an event listener to each and every similar element, we can add an event listener to a parent element and call an event on a particular target using the .target property of the event object.
Explain how this works in JavaScript
Explanation: this references an object. When inside of a constructor function or class it will reference the object on instantiation.
Use: It is used to assign properties and values to an object on instantiation.
Example:
class MyThing {
constructor(passThisIn) {
this.passThisIn = passThisIn;
}
}
Explain how prototypal inheritance works
Explanation: All JavaScript objects have a __proto__ property that is a reference to another object, which is called the object’s “prototype”. If a property is accessed on an object, but not found, the JavaScript engine check’s that object prototype. If again it’s not found, it checks that prototype’s prototype on up the chain until it reaches the top of the chain.
Use: It can help reduce redundant code.
What do you think of AMD vs CommonJS?
AMD and CommonJS are both Javascript module loader. They accomplish the same task but works different.
AMD is better for browser, hence, the name ‘Asynchronous’, as it loads each distinct module in async manner instead of loading in one large file. No extra steps are required to use AMD, it works out-of-the-box. In my opinion, as it is its in Asynchronous nature, it makes alot of async http requests and may not be as performant as described by other devs.
While, CommonJS, is a standard, mostly used in servers and it loads modules synchronously, though extra step is required if you want your JS file size to be minified and compressed.
Explain why the following doesn’t work as an IIFE: function foo(){ }();. What needs to be changed to properly make it an IIFE?
Explanation: The parser reads it as two seperate statements. First the function declaration function foo(){ } and then a blank function call attempt (); The best way to fix this would be to add another set of parenthesis wrapping the function declaration (function foo(){ })() This changes it from a function declaration to a function expression.
An IIFE (pronouced as ‘iffy’) is an abbreviation for Immediately Invoked Function Expression.
For the above code to be considered an IIFE, it needs to be an anonymous function, a function without a name, this is because IIFE needs to be Invoked Immediately without invoking it a function name. We also need to wrap the anonymous function with parenthesis, so the Javascript parser treats our anonymous function as a function expression.
(function() {}());
What’s the difference between a variable that is: null, undefined or undeclared? How would you go about checking for any of these states?
Explanation:
null: the value is intentionally absent (points to nothing in memory).
undefined: not yet assigned a value or not yet declared.
undeclared: improperly declared without let/const/var
Use: null can be used to assign the primitive value of null to a variable. undeclared throws an error where as null and undefined can be checked with a conditional
Example: null and undefined can be checked using strict equality ===. Undeclared will throw it’s own error so you could use try…catch
What is a closure, and how/why would you use one?
Explanation: Closure allows you to use an outer function’s scope (go into a parent, grandparent function, etc.) from within an inner function. In JavaScript a closure is created every time a function is created.
Use: It allows you to combine data with the function that will operate on that data. It is similar to OOP.
Example:
function init() {
var name = ‘Mozilla’; // name is a local variable created by init
function displayName() {
// displayName() is the inner function, a closure
alert(name); // use variable declared in the parent function
}
displayName();
}
init();
Can you describe the main difference between a .forEach loop and a .map() loop and why you would pick one versus the other?
Explanation: .forEach() executes a callback function on each element, but does not return a value. .map() executes a callback function on each element and “maps” the result to a new array. The new array is returned.
Use: If you need the result and don’t want to mutate the original array, use map. If you only need to iterate over the array then forEach can be used.
Example: .forEach():
const a = [1, 2, 3];
const doubled = a.forEach((num, index) => {
// Do something with num and/or index.
});
// doubled = undefined
.map():
const a = [1, 2, 3];
const doubled = a.map((num) => {
return num * 2;
});
// doubled = [2, 4, 6]
What’s a typical use case for anonymous functions?
Explanation: I’ve typically encountered them as callback functions that don’t need to be used anywhere else.
Use: Essentially when you don’t need a named function and the function is bound to some other action.
Example:
setTimeout(function () {
console.log(‘Hello world!’);
}, 1000);
How do you organize your code? (module pattern, classical inheritance?)
Explanation: My preference is to use ES6 Modules to organize my code.
Easier to reuse code
You can keep different parts of your code cleanly separated, which makes writing and maintaining your code much easier and less error-prone.
What’s the difference between host objects and native objects?
Explanation: Native objects are part of the language as defined by ECMAScript specification. Host objects are those provided by the runtime (browser or Node).
Example: Some native objects are String, Math, RegExp, and Object. A couple of host objects are window and console
Difference between:
function Person(){},
var person = Person(), and
var person = new Person()
function Person(){} is just a normal function declaration. It is likely being used as a constructor.
var person = new Person() is instantiated a new Person object as person. It creates an instance of the Person object using the new operator, which inherits from Person.prototype.
var person = Person() invokes the Person as a function, and not as a constructor. It is not correct and would likely return undefined. To create a new instance you would need to use the new operator as above.
Example:
function Person(name) {
this.name = name;
}
var person = Person(‘John’);
console.log(person); // undefined
console.log(person.name); // Uncaught TypeError: Cannot read property ‘name’ of undefined
var person = new Person(‘John’);
console.log(person); // Person { name: “John” }
console.log(person.name); // “john”
What’s the difference between .call and .apply?
Explanation: They are both used to invoke functions the difference is in how they take arguments. .call() takes them as comma-separated values and .apply() takes them as an array.
Explain Function.prototype.bind.
Explanation: Creates a new function that, when called, has its this keyword set to the provided value.
Use: For binding the value of this in methods of classes that you want to pass into other functions. This is frequently done in React components.
When would you use document.write()?
When document.write() is executed after page load, it replaces the entire header and body tag with the given parameter value in string. An invocation could look like this:
document.write(‘<h1>hello world</h1>’);
When working with web application, it is uncommon task to overwrite an entire page, hence why using document.write() is bad practice.
What’s the difference between feature detection, feature inference, and using the UA string?
Explanation:
Feature Detection: Working out whether a browser supports a certain block of code, and running different code depending on whether it does, so that the browser can provide a working experience rather crashing/erroring in some browsers.
Feature Inference: Checks for a feature just like feature detection, but uses another function because it assumes it will also exist. Feature Detection is the better approach.
UA String: A browser-reported string that allows the network protocol peers to identify various properties of the system. It’s tricky to parse and can be spoofed so it’s best to avoid this method.
Example: Using feature detection:
if (‘geolocation’ in navigator) {
// Can use navigator.geolocation
} else {
// Handle lack of feature
}
Explain Ajax in as much detail as possible.
Explanation: Ajax (asynchronous JavaScript and XML) is a set of web development techniques using many web technologies on the client side to create asynchronous web applications. With Ajax, web applications can send data to and retrieve from a server asynchronously (in the background) without interfering with the display and behavior of the existing page.
Use: By decoupling the data interchange layer from the presentation layer, Ajax allows for web pages, and by extension web applications, to change content dynamically without the need to reload the entire page. In practice, modern implementations commonly use JSON instead of XML, due to the advantages of JSON being native to JavaScript.
Example: The fetch API is typically used nowadays for asynchronous communication.
What are the advantages and disadvantages of using Ajax?
Advantages:
Better interactivity. New content from the server can be changed dynamically without the need to reload the entire page.
Reduce connections to the server since scripts and stylesheets only have to be requested once.
State can be maintained on a page. JavaScript variables and DOM state will persist because the main container page was not reloaded.
Disadvantages:
Dynamic webpages are harder to bookmark.
Does not work if JavaScript has been disabled in the browser.
Some webcrawlers do not execute JavaScript and would not see content that has been loaded by JavaScript.
JavaScript will have to be parsed and executed on the browser, and low-end mobile devices might struggle with this.
Explain how JSONP works (and how it’s not really Ajax).
Explanation: JSONP (JSON with Padding) is a method commonly used to bypass the cross-domain policies in web browsers because Ajax requests from the current page to a cross-origin domain is not allowed.
Use: JSONP can be unsafe as it can do everything else JavaScript can so you need to trust the provider of data. These days, CORS is the recommended approach and JSONP is seen as a hack.
Example:
<!-- https://mydomain.com -->
function printData(data) {
console.log(`My name is ${data.name}!`);
}
Have you ever used JavaScript templating? If so, what libraries have you used?
Explanation: The only one I’ve used is JSX in React, which I don’t think it quite javascript templating.
Use: It’s more of an extension to ECMAScript that allows you to easily structure components with familiar HTML syntax.
Example:
const name = ‘Josh Perez’;
const element = <h1>Hello, {name}</h1>;
Explain “hoisting”.
Explanation: It’s the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code. Think of it as moving the code up to the top. Note that the assignment stays where it is despite this.
Use: Allows you to execute code before they’re declared. Function declaration and var are initialized before delaration whereas const, let, and function expressions are not. This means the first two can be accessed globally and the last 3 only after they’ve been declared.
Example:
eat() //this hoisting works b.c it’s a function declaration below
function eat(){
console.log(‘eat’)
}
Describe event bubbling.
Explanation & Use: When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors. The most deeply nested element that caused the event is called a target element, accessible as event.target.
Example:
<style>
body * { margin: 10px; border: 1px solid blue; }</style>
<form>
FORM
<div>
DIV
<p>P</p>
</div>
</form>
When an event triggers on a DOM element, it will attempt to handle the event if there is a listener attached, then the event is bubbled up to its parent and the same thing happens. This bubbling occurs up the element’s ancestors all the way to the document. Event bubbling is the mechanism behind event delegation.
What’s the difference between an “attribute” and a “property”?
Explanation & Use: Attributes are defined on the HTML markup but properties are defined on the DOM. An attribute is the initial state when rendered in the DOM. A property is the current state.
Example:
const input = document.querySelector(‘input’);
console.log(input.getAttribute(‘value’)); // Hello
console.log(input.value); // Hello
Notice how the property updates after adding “World” to the input.
console.log(input.getAttribute(‘value’)); // Hello
console.log(input.value); // Hello World!
Attributes are defined on the HTML markup but properties are defined on the DOM. To illustrate the difference, imagine we have this text field in our HTML: <input></input>.
const input = document.querySelector(‘input’);
console.log(input.getAttribute(‘value’)); // Hello
console.log(input.value); // Hello
But after you change the value of the text field by adding “World!” to it, this becomes:
console.log(input.getAttribute(‘value’)); // Hello
console.log(input.value); // Hello World!
Why is extending built-in JavaScript objects not a good idea?
Extending a built-in/native JavaScript object means adding properties/functions to its prototype. While this may seem like a good idea at first, it is dangerous in practice. Imagine your code uses a few libraries that both extend the Array.prototype by adding the same contains method, the implementations will overwrite each other and your code will break if the behavior of these two methods is not the same.
The only time you may want to extend a native object is when you want to create a polyfill, essentially providing your own implementation for a method that is part of the JavaScript specification but might not exist in the user’s browser due to it being an older browser.