26/02 Flashcards

(44 cards)

1
Q

Explain the concept of tree shaking in module bundling

A

Tree shaking is a technique used in module bundling to eliminate dead code, which is code that is never used or executed.

This helps to reduce the final bundle size and improve application performance. It works by analyzing the dependency graph of the code and removing any unused exports. Tools like Webpack and Rollup support tree shaking when using ES6 module syntax (import and export).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How tree shaking works

A

Tree shaking works by analyzing the dependency graph of the code. It looks at the import and export statements to determine which parts of the code are actually used and which are not. The unused code, also known as dead code, is then removed from the final bundle.

Requirements for tree shaking
ES6 module syntax: Tree shaking relies on the static structure of ES6 module syntax (import and export). CommonJS modules (require and module.exports) are not statically analyzable and thus not suitable for tree shaking.
Bundler support: The bundler you are using must support tree shaking. Both Webpack and Rollup have built-in support for tree shaking.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Benefits of tree shaking

A

Reduced bundle size: By removing unused code, the final bundle size is reduced, leading to faster load times.

Improved performance: Smaller bundles mean less code to parse and execute, which can improve the performance of your application.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is the difference between == and === in JavaScript?

A

== is the abstract equality operator while === is the strict equality operator.

The == operator will compare for equality after doing any necessary type conversions.

The === operator will not do type conversion, so if two values are not the same type === will simply return false.

As a general rule of thumb, never use the == operator, except for convenience when comparing against null or undefined, where a == null will return true if a is null or undefined.

There’s also Object.is(value1, value2).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What’s the difference between a JavaScript variable that is: null, undefined or undeclared?

A

Undeclared
Undeclared variables are created when you assign a value to an identifier that is not previously created using var, let or const. Undeclared variables will be defined globally, outside of the current scope. In strict mode, a ReferenceError will be thrown when you try to assign to an undeclared variable. Undeclared variables are bad in the same way that global variables are bad. Avoid them at all cost! To check for them, wrap its usage in a try/catch block.

function foo() {
x = 1; // Throws a ReferenceError in strict mode
}

foo();
console.log(x); // 1

Using the typeof operator on undeclared variables will give ‘undefined’.

undefined
A variable that is undefined is a variable that has been declared, but not assigned a value. It is of type undefined. If a function does not return any value as the result of executing it is assigned to a variable, the variable also has the value of undefined. To check for it, compare using the strict equality (===) operator or typeof which will give the ‘undefined’ string. Note that you should not be using the loose equality operator (==) to check, as it will also return true if the value is null.

let foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === ‘undefined’); // true

null
A variable that is null will have been explicitly assigned to the null value. It represents no value and is different from undefined in the sense that it has been explicitly assigned. To check for null, simply compare using the strict equality operator. Note that like the above, you should not be using the loose equality operator (==) to check, as it will also return true if the value is undefined.

const foo = null;
console.log(foo === null); // true
console.log(typeof foo === ‘object’); // true

Notes
As a good habit, never leave your variables undeclared or unassigned. Explicitly assign null to them after declaring if you don’t intend to use them yet.
Always explicitly declare variables before using them to prevent errors.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What’s the difference between .call and .apply in JavaScript?

A

TL;DR
.call and .apply are both used to invoke functions with a specific this context and arguments. The primary difference lies in how they accept arguments:

.call(thisArg, arg1, arg2, …): Takes arguments individually.
.apply(thisArg, [argsArray]): Takes arguments as an array.

An easy way to remember this is C for call and comma-separated and A for apply and an array of arguments.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is the difference between mouseenter and mouseover event in JavaScript and browsers?

A

The main difference lies in the bubbling behavior of mouseenter and mouseover events. mouseenter does not bubble while mouseover bubbles.

mouseenter event:
Does not bubble: The mouseenter event does not bubble. It is only triggered when the mouse pointer enters the element to which the event listener is attached, not when it enters any child elements.

Triggered once: The mouseenter event is triggered only once when the mouse pointer enters the element, making it more predictable and easier to manage in certain scenarios.
A use case for mouseenter is when you want to detect the mouse entering an element without worrying about child elements triggering the event multiple times.

mouseover Event:
Bubbles up the DOM: The mouseover event bubbles up through the DOM. This means that if you have an event listener on a parent element, it will also trigger when the mouse pointer moves over any child elements.

Triggered multiple times: The mouseover event is triggered every time the mouse pointer moves over an element or any of its child elements. This can lead to multiple triggers if you have nested elements.

A use case for mouseover is when you want to detect when the mouse enters an element or any of its children and are okay with the events triggering multiple times.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What are the various data types in JavaScript?

A

TL;DR
In JavaScript, data types can be categorized into primitive and non-primitive types:

Primitive data types
Number: Represents both integers and floating-point numbers.
String: Represents sequences of characters.
Boolean: Represents true or false values.
Undefined: A variable that has been declared but not assigned a value.
Null: Represents the intentional absence of any object value.
Symbol: A unique and immutable value used as object property keys.
BigInt: Represents integers with arbitrary precision.

Non-primitive (Reference) data types:
Object: Used to store collections of data.
Array: An ordered collection of data.
Function: A callable object.
Date: Represents dates and times.
RegExp: Represents regular expressions.
Map: A collection of keyed data items.
Set: A collection of unique values.
The primitive types store a single value, while non-primitive types can store collections of data or complex entities.

JavaScript is a dynamically-typed language, which means variables can hold values of different data types over time. The typeof operator can be used to determine the data type of a value or variable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What are Symbols used for in JavaScript?

A

Symbols in JavaScript are a new primitive data type introduced in ES6 (ECMAScript 2015). They are unique and immutable identifiers that is primarily for object property keys to avoid name collisions.

Key characteristics
Uniqueness: Each Symbol value is unique, even if they have the same description.
Immutability: Symbol values are immutable, meaning their value cannot be changed.
Non-enumerable: Symbol properties are not included in for…in loops or Object.keys().

Global Symbol registry
You can create global Symbols using Symbol.for(‘key’), which creates a new Symbol in the global registry if it doesn’t exist, or returns the existing one. This allows you to reuse Symbols across different parts of your code base or even across different code bases.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is the difference between a Map object and a plain object in JavaScript?

A

Both Map objects and plain objects in JavaScript can store key-value pairs, but they have several key differences:

Plain JavaScript objects (POJO)
A plain object is a basic JavaScript object created using the {} syntax. It is a collection of key-value pairs, where each key is a string (or a symbol, in modern JavaScript) and each value can be any type of value, including strings, numbers, booleans, arrays, objects, and more.

Map objects
A Map object, introduced in ECMAScript 2015 (ES6), is a more advanced data structure that allows you to store key-value pairs with additional features. A Map is an iterable, which means you can use it with for…of loops, and it provides methods for common operations like get, set, has, and delete.

Key differences
Here are the main differences between a Map object and a plain object:

Key types: In a plain object, keys are always strings (or symbols).
In a Map, keys can be any type of value, including objects, arrays, and even other Maps.
Key ordering: In a plain object, the order of keys is not guaranteed.
In a Map, the order of keys is preserved, and you can iterate over them in the order they were inserted.
Iteration: A Map is iterable, which means you can use for…of loops to iterate over its key-value pairs.
A plain object is not iterable by default, but you can use Object.keys() or Object.entries() to iterate over its properties.
Performance: Map objects are generally faster and more efficient than plain objects, especially when dealing with large datasets.
Methods: A Map object provides additional methods, such as get, set, has, and delete, which make it easier to work with key-value pairs.
Serialization: When serializing a Map object to JSON, it will be converted to an object but the existing Map properties might be lost in the conversion. A plain object, on the other hand, is serialized to a JSON object with the same structure.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

When to use POJO vs Map?

A

When to use which
Use a plain object (POJO) when:

You need a simple, lightweight object with string keys.
You’re working with a small dataset.
You need to serialize the object to JSON (e.g. to send over the network).
Use a Map object when:

You need to store key-value pairs with non-string keys (e.g., objects, arrays).
You need to preserve the order of key-value pairs.
You need to iterate over the key-value pairs in a specific order.
You’re working with a large dataset and need better performance.

In summary, while both plain objects and Map objects can be used to store key-value pairs, Map objects offer more advanced features, better performance, and additional methods, making them a better choice for more complex use cases.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What are proxies in JavaScript used for?

A

In JavaScript, a proxy is an object that acts as an intermediary between an object and the code. Proxies are used to intercept and customize the fundamental operations of JavaScript objects, such as property access, assignment, function invocation, and more.

Here’s a basic example of using a Proxy to log every property access:

const myObject = {
name: ‘John’,
age: 42,
};

const handler = {
get: function (target, prop, receiver) {
console.log(Someone accessed property "${prop}");
return target[prop];
},
};

const proxiedObject = new Proxy(myObject, handler);

console.log(proxiedObject.name); // ‘John’
// Someone accessed property “name”

console.log(proxiedObject.value); // 42
// Someone accessed property “value”

This is useful for creating wrappers for logging and debugging interactions with an object.
Proxies can be used to validate property values before they are set on the target object.

Proxies are often used to trigger updates in other parts of your application when object properties change (data binding).

A practical example is JavaScript frameworks like Vue.js, where proxies are used to create reactive systems that automatically update the UI when data changes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Explain the concept of a callback function in asynchronous operations

A

A callback function is a function passed as an argument to another function, which is then invoked inside the outer function to complete some kind of routine or action. In asynchronous operations, callbacks are used to handle tasks that take time to complete, such as network requests or file I/O, without blocking the execution of the rest of the code. For example:

A callback function is a function passed as an argument to another function, which is then invoked inside the outer function to complete some kind of routine or action. In asynchronous operations, callbacks are used to handle tasks that take time to complete, such as network requests or file I/O, without blocking the execution of the rest of the code. For example:

Common use cases
Network requests: Fetching data from an API
File I/O: Reading or writing files
Timers: Delaying execution using setTimeout or setInterval
Event handling: Responding to user actions like clicks or key presses

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Explain the concept of a microtask queue

A

The microtask queue is a queue of tasks that need to be executed after the currently executing script and before any other task. Microtasks are typically used for tasks that need to be executed immediately after the current operation, such as promise callbacks. The microtask queue is processed before the macrotask queue, ensuring that microtasks are executed as soon as possible.

How does the microtask queue work?
Execution order: The microtask queue is processed after the currently executing script and before the macrotask queue. This means that microtasks are given higher priority over macrotasks.
Event loop: During each iteration of the event loop, the JavaScript engine first processes all the microtasks in the microtask queue before moving on to the macrotask queue.
Adding microtasks: Microtasks can be added to the microtask queue using methods like Promise.resolve().then() and queueMicrotask().

Use cases
Promise callbacks: Microtasks are commonly used for promise callbacks to ensure they are executed as soon as possible after the current operation.
MutationObserver: The MutationObserver API uses microtasks to notify changes in the DOM.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Explain the concept of caching and how it can be used to improve performance

A

Caching is a technique used to store copies of files or data in a temporary storage location to reduce the time it takes to access them. It improves performance by reducing the need to fetch data from the original source repeatedly. In front end development, caching can be implemented using browser cache, service workers, and HTTP headers like Cache-Control.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What is browser caching?

A

The browser cache stores copies of web pages, images, and other resources locally on the user’s device. When a user revisits a website, the browser can load these resources from the cache instead of fetching them from the server, resulting in faster load times.

<head>
<link></link>



</head>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What are Service workers?

A

Service workers are scripts that run in the background and can intercept network requests. They can cache resources and serve them from the cache, even when the user is offline. This can significantly improve performance and provide a better user experience.

self.addEventListener(‘install’, (event) => {
event.waitUntil(
caches.open(‘v1’).then((cache) => {
return cache.addAll([‘/index.html’, ‘/styles.css’, ‘/app.js’]);
}),
);
});

self.addEventListener(‘fetch’, (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
}),
);
});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What is HTTP caching?

A

HTTP caching involves using HTTP headers to control how and when resources are cached. Common headers include Cache-Control, Expires, and ETag.

Cache-Control: max-age=3600

19
Q

How does caching improve performance?

A

Reduced latency
By storing frequently accessed data closer to the user, caching reduces the time it takes to retrieve that data. This results in faster load times and a smoother user experience.

Reduced server load
Caching reduces the number of requests made to the server, which can help decrease server load and improve overall performance.

Offline access
With service workers, cached resources can be served even when the user is offline, providing a seamless experience.

20
Q

Explain the concept of code coverage and how it can be used to assess test quality

A

Code coverage is a metric that measures the percentage of code that is executed when the test suite runs. It helps in assessing the quality of tests by identifying untested parts of the codebase. Higher code coverage generally indicates more thorough testing, but it doesn’t guarantee the absence of bugs. Tools like Istanbul or Jest can be used to measure code coverage.

Types of code coverage
Statement coverage: Measures the number of statements in the code that have been executed.
Branch coverage: Measures whether each branch (e.g., if and else blocks) has been executed.
Function coverage: Measures whether each function in the code has been called.
Line coverage: Measures the number of lines of code that have been executed.
Condition coverage: Measures whether each boolean sub-expression has been evaluated to both true and false.

21
Q

Pros/cons of code coverage?

A

Benefits
Identifies untested code: Helps in finding parts of the codebase that are not covered by tests.
Improves test suite: Encourages writing more comprehensive tests.
Increases confidence: Higher coverage can increase confidence in the stability of the code.

Limitations
False sense of security: High coverage does not guarantee the absence of bugs.
Quality over quantity: 100% coverage does not mean the tests are of high quality. Tests should also check for edge cases and potential errors.

22
Q

Explain the concept of Content Security Policy (CSP) and how it enhances security?

A

Content Security Policy (CSP) is a security feature that helps prevent various types of attacks, such as Cross-Site Scripting (XSS) and data injection attacks, by specifying which content sources are trusted. It works by allowing developers to define a whitelist of trusted sources for content like scripts, styles, and images. This is done through HTTP headers or meta tags. For example, you can use the Content-Security-Policy header to specify that only scripts from your own domain should be executed:

Content-Security-Policy: script-src ‘self’

23
Q

What is Content Security Policy (CSP)?

A

Content Security Policy (CSP) is a security standard introduced to mitigate a range of attacks, including Cross-Site Scripting (XSS) and data injection attacks. CSP allows web developers to control the resources that a user agent is allowed to load for a given page. By specifying a whitelist of trusted content sources, CSP helps to prevent the execution of malicious content.

24
Q

How does CSP work?

A

CSP works by allowing developers to define a set of rules that specify which sources of content are considered trustworthy. These rules are delivered to the browser via HTTP headers or meta tags. When the browser loads a page, it checks the CSP rules and blocks any content that does not match the specified sources.

Example of a CSP header
Here is an example of a simple CSP header that only allows scripts from the same origin:

Content-Security-Policy: script-src ‘self’

Common directives
default-src: Serves as a fallback for other resource types when they are not explicitly defined.
script-src: Specifies valid sources for JavaScript.
style-src: Specifies valid sources for CSS.
img-src: Specifies valid sources for images.
connect-src: Specifies valid sources for AJAX, WebSocket, and EventSource connections.
font-src: Specifies valid sources for fonts.
object-src: Specifies valid sources for plugins like Flash.

25
Benefits of using CSP?
Mitigates XSS attacks: By restricting the sources from which scripts can be loaded, CSP helps to prevent the execution of malicious scripts. Prevents data injection attacks: CSP can block the loading of malicious resources that could be used to steal data or perform other harmful actions. Improves security posture: Implementing CSP is a proactive measure that enhances the overall security of a web application.
26
How do you implement CSP?
CSP can be implemented using HTTP headers or meta tags. The HTTP header approach is generally preferred because it is more secure and cannot be easily overridden by attackers. Using HTTP headers Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com Using meta tags
27
Explain the concept of error propagation in JavaScript
Error propagation in JavaScript refers to how errors are passed through the call stack. When an error occurs in a function, it can be caught and handled using try...catch blocks. If not caught, the error propagates up the call stack until it is either caught or causes the program to terminate. For example: function a() { throw new Error('An error occurred'); } function b() { a(); } try { b(); } catch (e) { console.error(e.message); // Outputs: An error occurred Error propagation in JavaScript is a mechanism that allows errors to be passed up the call stack until they are caught and handled. This is crucial for debugging and ensuring that errors do not cause the entire application to crash unexpectedly. How errors propagate When an error occurs in a function, it can either be caught and handled within that function or propagate up the call stack to the calling function. If the calling function does not handle the error, it continues to propagate up the stack until it reaches the global scope, potentially causing the program to terminate.
28
How can you handle errors and prevent them propogating further?
Using try...catch blocks Error propagation works differently with asynchronous code, such as promises and async/await. For promises, you can use .catch() to handle errors: function a() { return Promise.reject(new Error('An error occurred')); } function b() { return a(); } b().catch((e) => { console.error(e.message); // Outputs: An error occurred }); Best practices Always handle errors at the appropriate level to prevent them from propagating unnecessarily. Use try...catch blocks for synchronous code and .catch() or try...catch with async/await for asynchronous code. Log errors to help with debugging and provide meaningful error messages to users.
29
Explain the concept of inheritance in ES2015 classes
Inheritance in ES2015 classes allows one class to extend another, enabling the child class to inherit properties and methods from the parent class. This is done using the extends keyword. The super keyword is used to call the constructor and methods of the parent class. Here's a quick example: class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } speak() { console.log(`${this.name} barks.`); } } const dog = new Dog('Rex', 'German Shepherd'); dog.speak(); // Rex barks. Using the extends keyword The extends keyword is used to create a class that is a child of another class. The child class inherits all the properties and methods of the parent class. Using the super keyword The super keyword is used to call the constructor of the parent class and to access its methods. This is necessary when you want to initialize the parent class properties in the child class.
30
Explain the concept of input validation and its importance in security
Input validation is the process of ensuring that user input is correct, safe, and meets the application's requirements. It is crucial for security because it helps prevent attacks like SQL injection, cross-site scripting (XSS), and other forms of data manipulation. By validating input, you ensure that only properly formatted data enters your system, reducing the risk of malicious data causing harm.
31
What is input validation?
Input validation is the process of verifying that the data provided by a user or other external sources meets the expected format, type, and constraints before it is processed by the application. This can include checking for: Correct data type (e.g., string, number) Proper format (e.g., email addresses, phone numbers) Acceptable value ranges (e.g., age between 0 and 120) Required fields being filled
32
Types of input validation?
Client-side validation: This occurs in the user's browser before the data is sent to the server. It provides immediate feedback to the user and can improve the user experience. However, it should not be solely relied upon for security purposes, as it can be easily bypassed.
Server-side validation: This occurs on the server after the data has been submitted. It is essential for security because it ensures that all data is validated regardless of the client's behavior. const express = require('express'); const app = express(); app.post('/submit', (req, res) => { const username = req.body.username; if (!/^[A-Za-z0-9]{5,}$/.test(username)) { return res.status(400).send('Invalid username'); } // Proceed with processing the valid input });
33
What's the importance of input validation in security
Preventing SQL injection: By validating and sanitizing input, you can prevent attackers from injecting malicious SQL code into your database queries. Preventing cross-site scripting (XSS): Input validation helps ensure that user input does not contain malicious scripts that could be executed in the browser. Preventing buffer overflow attacks: By validating the length of input data, you can prevent attackers from sending excessively large inputs that could cause buffer overflows and crash your application. Ensuring data integrity: Input validation helps maintain the integrity of your data by ensuring that only properly formatted and expected data is processed and stored. Best practices for input validation Always validate input on the server side, even if you also validate on the client side Use built-in validation functions and libraries where possible Sanitize input to remove or escape potentially harmful characters Implement whitelisting (allowing only known good input) rather than blacklisting (blocking known bad input) Regularly update and review your validation rules to address new security threats
34
Explain the concept of the Web Socket API
The WebSocket API provides a way to open a persistent connection between a client and a server, allowing for real-time, two-way communication. Unlike HTTP, which is request-response based, WebSocket enables full-duplex communication, meaning both the client and server can send and receive messages independently. This is particularly useful for applications like chat apps, live updates, and online gaming.
35
Key features of WebSocket API
Key features Full-duplex communication: Both the client and server can send and receive messages independently. Low latency: The persistent connection reduces the overhead of establishing a new connection for each message. Real-time updates: Ideal for applications that require real-time data, such as chat applications, live sports updates, and online gaming.
36
What is WebSocket API
The WebSocket API is a technology that provides a way to establish a persistent, low-latency, full-duplex communication channel between a client (usually a web browser) and a server. This is different from the traditional HTTP request-response model, which is stateless and requires a new connection for each request.
37
How WebSocket API works
Connection establishment: The client initiates a WebSocket connection by sending a handshake request to the server. Handshake response: The server responds with a handshake response, and if successful, the connection is established. Data exchange: Both the client and server can now send and receive messages independently over the established connection. Connection closure: Either the client or server can close the connection when it is no longer needed. Use cases Chat applications: Real-time messaging between users. Live updates: Stock prices, sports scores, or news updates. Online gaming: Real-time interaction between players. Collaborative tools: Real-time document editing or whiteboarding.
38
Explain the concept of `this` binding in event handlers
In JavaScript, the this keyword refers to the object that is currently executing the code. In event handlers, this typically refers to the element that triggered the event. However, the value of this can change depending on how the event handler is defined and called. To ensure this refers to the desired object, you can use methods like bind(), arrow functions, or assign the context explicitly. The value of this is determined by how a function is called, not where it is defined. This can lead to different values of this in different contexts. In the context of event handlers, this usually refers to the DOM element that triggered the event. Using bind() The bind() method creates a new function that, when called, has its this keyword set to the provided value: function handleClick() { console.log(this); // Logs the object passed to bind() } const obj = { name: 'MyObject' }; document .getElementById('myButton') .addEventListener('click', handleClick.bind(obj)); Using arrow functions Arrow functions do not have their own this context; they inherit this from the surrounding lexical context.
39
Describe the difference between a cookie, `sessionStorage` and `localStorage` in browsers
TL;DR All of the following are mechanisms of storing data on the client, the user's browser in this case. localStorage and sessionStorage both implement the Web Storage API interface. Cookies: Suitable for server-client communication, small storage capacity, can be persistent or session-based, domain-specific. Sent to the server on every request. localStorage: Suitable for long-term storage, data persists even after the browser is closed, accessible across all tabs and windows of the same origin, highest storage capacity among the three. sessionStorage: Suitable for temporary data within a single page session, data is cleared when the tab or window is closed, has a higher storage capacity compared to cookies.
40
What should you store in cookies?
Since cookies have a relatively low maximum size, it is not advisable to store all your client-side data within cookies. The distinguishing properties about cookies are that cookies are sent to the server on every HTTP request so the low maximum size is a feature that prevents your HTTP requests from being too large due to cookies. Automatic expiry of cookies is a useful feature as well. With that in mind, the best kind of data to store within cookies is small pieces of data that needs to be transmitted to the server, such as auth tokens, session IDs, analytics tracking IDs, GDPR cookie consent, language preferences that are important for authentication, authorization, and rendering on the server. These values are sometimes sensitive and can benefit from the HttpOnly, Secure, and Expires/Max-Age capabilities that cookies provide.
41
What should you store in local/session storage?
localStorage and sessionStorage both implement the Web Storage API interface. Web Storages have a generous total capacity of 5MB, so storage size is usually not a concern. The key difference is that values stored in Web Storage are not automatically sent along HTTP requests. While you can manually include values from Web Storage when making AJAX/fetch() requests, the browser does not include them in the initial request / first load of the page. Hence Web Storage should not be used to store data that is relied on by the server for the initial rendering of the page if server-side rendering is being used (typically authentication/authorization-related information). localStorage is most suitable for user preferences data that do not expire, like themes and layouts (if it is not important for the server to render the final layout). sessionStorage is most suitable for temporary data that only needs to be accessible within the current browsing session, such as form data (useful to preserve data during accidental reloads).
42
What's a cookie?
Cookies Cookies are used to store small pieces of data on the client side that can be sent back to the server with every HTTP request. Storage capacity: Limited to around 4KB for all cookies. Lifespan: Cookies can have a specific expiration date set using the Expires or Max-Age attributes. If no expiration date is set, the cookie is deleted when the browser is closed (session cookie). Access: Cookies are domain-specific and can be shared across different pages and subdomains within the same domain. Security: Cookies can be marked as HttpOnly to prevent access from JavaScript, reducing the risk of XSS attacks. They can also be secured with the Secure flag to ensure they are sent only when HTTPS is used. It is a pain to read/write to cookies. document.cookie returns a single string containing all the key/value pairs delimited by ; and you have to parse the string yourself. The js-cookie npm library provides a simple and lightweight API for reading/writing cookies in JavaScript. A modern native way of accessing cookies is via the Cookie Store API which is only available on HTTPS pages. // Set a cookie. More options are available too. cookieStore.set('auth_token', 'abc123def'); // Async method to access a single cookie and do something with it. cookieStore.get('auth_token').then(...); // Async method to get all cookies. cookieStore.getAll().then(...); // Async method to delete a single cookie. cookieStore.delete('auth_token').then(() => console.log('Cookie deleted') );
43
What is local storage?
localStorage localStorage is used for storing data that persists even after the browser is closed and reopened. It is designed for long-term storage of data. Storage capacity: Typically around 5MB per origin (varies by browser). Lifespan: Data in localStorage persists until explicitly deleted by the user or the application. Access: Data is accessible within all tabs and windows of the same origin. Security: All JavaScript on the page have access to values within localStorage. // Set a value in localStorage.
44
What is session storage?
sessionStorage is used to store data for the duration of the page session. It is designed for temporary storage of data. Storage Capacity: Typically around 5MB per origin (varies by browser). Lifespan: Data in sessionStorage is cleared when the page session ends (i.e., when the browser or tab is closed). Reloading the page does not destroy data within sessionStorage. Access: Data is only accessible within the current tab or window. Different tabs or windows with the same page will have different sessionStorage objects. Security: All JavaScript on the same page have access to values within sessionStorage for that page.