misc: add affilliate

This commit is contained in:
Yangshun 2024-06-07 16:17:17 +08:00
parent fc1cfc555f
commit e5f99b68ba
74 changed files with 1618 additions and 1792 deletions

View File

@ -1,6 +1,6 @@
<div align="center">
<h1>Front End Interview Handbook</h1>
<p>By <a href="https://www.greatfrontend.com">GreatFrontEnd</a></p>
<p>By <a href="https://www.greatfrontend.com/?fpr=yangshun">GreatFrontEnd</a></p>
</div>
<div align="center">
@ -24,7 +24,7 @@
<p dir="auto"></p>
<a href="https://www.greatfrontend.com/prepare/" target="_blank">
<a href="https://www.greatfrontend.com/prepare/?fpr=yangshun" target="_blank">
<img src="assets/start-practicing-button.jpg" alt="Start Practicing Front End Questions on GreatFrontEnd" />
</a>
@ -41,22 +41,22 @@ Unlike typical software engineer job interviews, front end job interviews have l
## Where to get hands on practice?
<div align="center">
<a href="https://www.greatfrontend.com">
<a href="https://www.greatfrontend.com?fpr=yangshun">
<img src="assets/mark-brand-light.png" alt="GreatFrontEnd" width="400"/>
</a>
</div>
After getting a good understanding about front end interview preparation, try out [GreatFrontEnd](https://www.greatfrontend.com), a platform built by me! Not only that there are 200+ practice questions, each with multiple solutions from senior front end engineers, there are also automated test case suites to help you identify what's wrong with your code. Thus, check out the following resources:
After getting a good understanding about front end interview preparation, try out [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun), a platform built by me! Not only that there are 200+ practice questions, each with multiple solutions from senior front end engineers, there are also automated test case suites to help you identify what's wrong with your code. Thus, check out the following resources:
- [Study plans](https://www.greatfrontend.com/study-plans) help you prepare for your upcoming technical interviews, whether it is in a week or 3 months later.
- [Focus areas](https://www.greatfrontend.com/focus-areas) allow you to focus on your weak areas and also further improve your strengths depending on your preferences.
- [Preparation by stage](https://www.greatfrontend.com/prepare) prepares you for each phase of your interview process, from quiz to coding interviews.
- [Individual framework questions](https://www.greatfrontend.com/questions) offer training based on specific frameworks that may be tested during your technical interviews.
- [Study plans](https://www.greatfrontend.com/study-plans?fpr=yangshun) help you prepare for your upcoming technical interviews, whether it is in a week or 3 months later.
- [Focus areas](https://www.greatfrontend.com/focus-areas?fpr=yangshun) allow you to focus on your weak areas and also further improve your strengths depending on your preferences.
- [Preparation by stage](https://www.greatfrontend.com/prepare?fpr=yangshun) prepares you for each phase of your interview process, from quiz to coding interviews.
- [Individual framework questions](https://www.greatfrontend.com/questions?fpr=yangshun) offer training based on specific frameworks that may be tested during your technical interviews.
---
<div align="center">
<h3>Need to practice front end interview questions? <a href="https://www.greatfrontend.com">GreatFrontEnd</a> is holding a limited time promotion for 20% off their lifetime plan of high quality practice questions and reference solutions written by ex-FAANG interviewers 🚀</h3>
<h3>Need to practice front end interview questions? <a href="https://www.greatfrontend.com?fpr=yangshun">GreatFrontEnd</a> is holding a limited time promotion for 20% off their lifetime plan of high quality practice questions and reference solutions written by ex-FAANG interviewers 🚀</h3>
</div>
---

View File

@ -6,7 +6,7 @@ sidebar_label: Algorithms coding
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/algorithms).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/algorithms?fpr=yangshun).
:::
@ -22,7 +22,7 @@ The [Tech Interview Handbook](https://www.techinterviewhandbook.org/algorithms/s
### GreatFrontEnd
[GreatFrontEnd](https://www.greatfrontend.com) provides **free** questions for you to practice implementing [Data Structures and Algorithms](https://www.greatfrontend.com/questions/js/coding/data-structures-algorithms) in JavaScript. You can practice implementing common data structures (e.g. [Stacks](https://www.greatfrontend.com/questions/javascript/stack), [Queues](https://www.greatfrontend.com/questions/javascript/queue)) and algorithms (e.g. [Binary Search](https://www.greatfrontend.com/questions/javascript/binary-search), [Merge Sort](https://www.greatfrontend.com/questions/javascript/merge-sort)). [**Check it out →**](https://www.greatfrontend.com/questions/js/coding/data-structures-algorithms)
[GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun) provides **free** questions for you to practice implementing [Data Structures and Algorithms](https://www.greatfrontend.com/questions/js/coding/data-structures-algorithms?fpr=yangshun) in JavaScript. You can practice implementing common data structures (e.g. [Stacks](https://www.greatfrontend.com/questions/javascript/stack?fpr=yangshun), [Queues](https://www.greatfrontend.com/questions/javascript/queue?fpr=yangshun)) and algorithms (e.g. [Binary Search](https://www.greatfrontend.com/questions/javascript/binary-search?fpr=yangshun), [Merge Sort](https://www.greatfrontend.com/questions/javascript/merge-sort?fpr=yangshun)). [**Check it out →**](https://www.greatfrontend.com/questions/js/coding/data-structures-algorithms?fpr=yangshun)
## Algorithm courses

View File

@ -4,7 +4,7 @@ title: Behavorial interview
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/behavioral-interview-guidebook).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/behavioral-interview-guidebook?fpr=yangshun).
:::
@ -22,7 +22,7 @@ Behavioral interview rounds focus on a candidate's soft skills - how they work w
_Source: [Preparing for your Onsite Interview at Facebook](https://www.facebook.com/careers/swe-prep-onsite)_
Do check out [GreatFrontEnd](https://www.greatfrontend.com) for its free [Behavioral Interview Guidebook](https://www.greatfrontend.com/behavioral-interview-guidebook) to learn how to approach behavioral interviews as a front end engineer. Find out about evaluation criteria at big tech, efficient strategies to prepare, and top behavioral interview questions.
Do check out [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun) for its free [Behavioral Interview Guidebook](https://www.greatfrontend.com/behavioral-interview-guidebook?fpr=yangshun) to learn how to approach behavioral interviews as a front end engineer. Find out about evaluation criteria at big tech, efficient strategies to prepare, and top behavioral interview questions.
## Courses

View File

@ -6,7 +6,7 @@ sidebar_label: User interface coding
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/user-interface).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/user-interface?fpr=yangshun).
:::
@ -22,26 +22,26 @@ Companies that ask such questions usually ask candidates to code in one of these
## Examples
- Components
- Tabs — [Practice](https://www.greatfrontend.com/questions/user-interface/tabs) (Paid)
- Accordion — [Practice](https://www.greatfrontend.com/questions/user-interface/accordion) (Paid)
- Tabs — [Practice](https://www.greatfrontend.com/questions/user-interface/tabs?fpr=yangshun) (Paid)
- Accordion — [Practice](https://www.greatfrontend.com/questions/user-interface/accordion?fpr=yangshun) (Paid)
- Photo Gallery
- Other possible components - [Refer to Bootstrap's list](https://getbootstrap.com/docs/5.3/components/)
- Apps
- TODO list — [Practice](https://www.greatfrontend.com/questions/user-interface/todo-list) (Free)
- Todo list — [Practice](https://www.greatfrontend.com/questions/user-interface/todo-list?fpr=yangshun) (Free)
- Sortable Data Table (with extensions for filtering)
- Kanban Board
- Games
- Tic-tac-toe — [Practice](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe) (Paid)
- Whack-a-mole — [Practice](https://www.greatfrontend.com/questions/user-interface/whack-a-mole) (Paid)
- Wordle — [Practice](https://www.greatfrontend.com/questions/user-interface/wordle) (Paid)
- Tic-tac-toe — [Practice](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe?fpr=yangshun) (Paid)
- Whack-a-mole — [Practice](https://www.greatfrontend.com/questions/user-interface/whack-a-mole?fpr=yangshun) (Paid)
- Wordle — [Practice](https://www.greatfrontend.com/questions/user-interface/wordle?fpr=yangshun) (Paid)
- Tetris (advanced)
- Snake (advanced)
## Where to practice
- Each of these questions and over 200+ more can be found on [GreatFrontEnd](https://www.greatfrontend.com).
- Each of these questions and over 200+ more can be found on [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun).
- Each question comes with official solutions in popular frameworks such as React, Angular, Svelte and Vue.
- With live previews, you can practice online directly, simulating a real interview environment with no set-up required.
- [Start practicing immediately](https://www.greatfrontend.com/questions)
- [Start practicing immediately](https://www.greatfrontend.com/questions?fpr=yangshun)
## Considerations

View File

@ -5,7 +5,7 @@ sidebar_label: Airbnb interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -17,9 +17,9 @@ Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfro
## User interface coding
- Given an input and an endpoint which returns a JSON list, as a result, extend it to autocomplete on change, handle key navigation through the results.
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete) (Free)
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete?fpr=yangshun) (Free)
- Given a star widget embedded in a form write the code to select the stars and submit the correct value through a normal form action. Make reusable for multiple star widgets.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/star-rating) (Free)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/star-rating?fpr=yangshun) (Free)
_Source: [Glassdoor Airbnb Front End Engineer Interview Questions](https://www.glassdoor.sg/Interview/Airbnb-Front-End-Engineer-Interview-Questions-EI_IE391850.0,6_KO7,25.htm)_

View File

@ -5,7 +5,7 @@ sidebar_label: Amazon interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -19,35 +19,35 @@ Refer to Amazon's official interview preparation guides for:
## Trivia
- What is the CSS box model?
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-your-understanding-of-the-box-model-and-how-you-would-tell-the-browser-in-css-to-render-your-layout-in-different-box-models) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-your-understanding-of-the-box-model-and-how-you-would-tell-the-browser-in-css-to-render-your-layout-in-different-box-models?fpr=yangshun) (Free)
- What is a JavaScript closure?
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-a-closure-and-how-why-would-you-use-one) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-a-closure-and-how-why-would-you-use-one?fpr=yangshun) (Free)
- What happens when you type URL into a browser and hit enter?
## JavaScript
- Implement `Array.prototype` functions like `map`, `reduce`, `filter`, `sort`.
- [Practice questions](https://www.greatfrontend.com/questions/js/coding/utilities)
- [Practice questions](https://www.greatfrontend.com/questions/js/coding/utilities?fpr=yangshun)
- Given an object and a filter function, write a function that recursively filters the object, returning only values which return `true` when called with the filter function (like `Array.prototype.filter` but for objects).
- Implement a function `getElementsByStyle(property, value)` that returns all elements in the DOM that match that style.
- E.g. `getElementsByStyle("color", "#fff")` will return all elements in the DOM with white text.
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-class-name) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-class-name?fpr=yangshun) (Paid)
- Promisify a function.
## User interface coding
- Implement a data table from an array of objects using HTML/CSS and JavaScript with searching and sorting.
- [Practice question](https://www.greatfrontend.com/questions/javascript/data-selection) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/data-selection?fpr=yangshun) (Paid)
- Implement Material UI Chips with auto-suggest. When sending an e-mail, auto-suggest people and convert them into a chip with their avatar on the right
- Implement a Like button. [Source](https://leetcode.com/discuss/interview-question/1719943/Amazon-or-Phone-Screen-or-FEE-L5-or-Like-Button)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/like-button) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/like-button?fpr=yangshun) (Paid)
- Code a paginated widget of addresses. Imagine you are a seller with a list of address you ship to an need to view them 5 address per page, with the possibility to go previous and next. [Source](<https://leetcode.com/discuss/interview-question/1984996/Amazon-Virtual-Onsite-April-2022-FrontEnd-Engineer-II-(L5)Vancouver-Offer>)
- Implement a search bar using HTML, CSS and JavaScript.
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete) (Free)
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete?fpr=yangshun) (Free)
- Implement a star rating widget.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/star-rating) (Free)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/star-rating?fpr=yangshun) (Free)
- Implement tic-tac-toe.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe?fpr=yangshun) (Paid)
- Recreate an adaptive layout with flexbox. Ensure accessibility.
- Implement a chess board with movable pieces.
- How do you render text on a banner image?
@ -57,7 +57,7 @@ Refer to Amazon's official interview preparation guides for:
- Design a restaurant listing application where user can make orders and customize their orders by adding additional stuffs like toppings, salads etc. [Source](<https://leetcode.com/discuss/interview-question/1984996/Amazon-Virtual-Onsite-April-2022-FrontEnd-Engineer-II-(L5)Vancouver-Offer>)
- Design an accordion component.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/accordion) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/accordion?fpr=yangshun) (Paid)
## Algorithm

View File

@ -5,7 +5,7 @@ sidebar_label: Apple interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -14,7 +14,7 @@ Not much is known about Apple's front end interview process.
## JavaScript
- Implement `Array.prototype` methods (`flat`, `map`, `reduce`, `concat`) by yourself using JavaScript.
- [Practice questions](https://www.greatfrontend.com/questions/coding)
- [Practice questions](https://www.greatfrontend.com/questions/coding?fpr=yangshun)
- How can you execute an array of promise in sequence?
## User interface coding

View File

@ -5,7 +5,7 @@ sidebar_label: ByteDance/TikTok interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -14,19 +14,19 @@ ByteDance/TikTok's front end interview is quite balanced in terms of interview f
## JavaScript
- Implement `Promise.all`.
- [Practice question](https://www.greatfrontend.com/questions/javascript/promise-all) (Free)
- [Practice question](https://www.greatfrontend.com/questions/javascript/promise-all?fpr=yangshun) (Free)
- Implement a function which extends `Array.prototype`.
- [Practice questions](https://www.greatfrontend.com/prepare/coding)
- [Practice questions](https://www.greatfrontend.com/prepare/coding?fpr=yangshun)
## User interface coding
- Implement a dropdown component.
- [Read answer](https://www.greatfrontend.com/questions/system-design/dropdown-menu) (Paid)
- [Read answer](https://www.greatfrontend.com/questions/system-design/dropdown-menu?fpr=yangshun) (Paid)
## Trivia
- Difference between `localStorage` and cookies.
- [Read answer](https://www.greatfrontend.com/questions/quiz/describe-the-difference-between-a-cookie-sessionstorage-and-localstorage) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/describe-the-difference-between-a-cookie-sessionstorage-and-localstorage?fpr=yangshun) (Free)
## Algorithm

View File

@ -5,7 +5,7 @@ sidebar_label: Dropbox interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -18,13 +18,13 @@ Refer to the [full official Dropbox Web Developer Interview Preparation Guide](/
## JavaScript
- Implement [`getByClassName()` and `getByClassnameHierarchy()`](https://leetcode.com/discuss/interview-question/427896/Dropbox-or-Phone-Screen-or-Implement-getByClassName-and-getByClassnameHierarchy)
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-class-name) (Free)
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-class-name?fpr=yangshun) (Free)
- OOP-based class management system.
## User interface coding
- Build an image gallery using JavaScript, HTML, CSS.
- [Read answer](https://www.greatfrontend.com/questions/system-design/image-carousel) (Free)
- [Read answer](https://www.greatfrontend.com/questions/system-design/image-carousel?fpr=yangshun) (Free)
- Forming words from mobile keypad.
- Build a UI that fetches data from a weather API that is matching a design spec.
- Build a UI that matches a design spec of one of the pages on the Dropbox homepage.

View File

@ -5,7 +5,7 @@ sidebar_label: Google interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -22,26 +22,26 @@ Refer to Google's official interview preparation guides for:
## JavaScript
- How do you make a function that takes a callback function `fn` and returns a function that calls `fn` on a timeout?
- [Practice question](https://www.greatfrontend.com/questions/javascript/debounce) (Free)
- [Practice question](https://www.greatfrontend.com/questions/javascript/debounce?fpr=yangshun) (Free)
- Implement the outline view for a Google doc.
- [Practice question](https://www.greatfrontend.com/questions/javascript/table-of-contents) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/table-of-contents?fpr=yangshun) (Paid)
- DFS on HTML nodes.
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-tag-name) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-tag-name?fpr=yangshun) (Paid)
- Implement `throttle`.
- [Practice question](https://www.greatfrontend.com/questions/javascript/throttle) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/throttle?fpr=yangshun) (Paid)
- How do you make a function that only calls input function f every 50 milliseconds?
- [Practice question](https://www.greatfrontend.com/questions/javascript/throttle) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/throttle?fpr=yangshun) (Paid)
- Given a timeline write the JavaScript to select all nodes within selection of timeline.
## User interface coding
- Design a slider component.
- Design a Tic-Tac-Toe game/design an algorithm for Tic-Tac-Toe game.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe?fpr=yangshun) (Paid)
- Implement nested checkboxes (when the parent is checked, children are checked and vice versa. Use `<input type="checkbox">`). Similar to [Indeterminate checkboxes](https://css-tricks.com/indeterminate-checkboxes/).
- Design a webpage which can auto load new posts when you reach the bottom of the page by using JavaScript. You may use AJAX and JavaScript event listeners.
- Write a UI using HTML, CSS, JavaScript that allows uses to enter the number of rows and columns in text input fields within a form and renders a table.
- [Practice question](https://www.greatfrontend.com/questions/javascript/throttle) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/throttle?fpr=yangshun) (Paid)
- Example: Number of rows: 4, Number of columns: 5, "Submit" button. Clicking on the "Submit" button will show the following table (ignore the styling):
| 1 | 8 | 9 | 16 | 17 |
@ -53,16 +53,16 @@ Refer to Google's official interview preparation guides for:
## Trivia
- Explain the CSS Box Model.
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-your-understanding-of-the-box-model-and-how-you-would-tell-the-browser-in-css-to-render-your-layout-in-different-box-models) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-your-understanding-of-the-box-model-and-how-you-would-tell-the-browser-in-css-to-render-your-layout-in-different-box-models?fpr=yangshun) (Free)
- What happens when you type a URL into the browser and hits enter?
- Given some text on a web page, how many ways can you make the text disappear?
- How do you send data from a web page to a server without a page refresh?
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-are-the-advantages-and-disadvantages-of-using-ajax) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-are-the-advantages-and-disadvantages-of-using-ajax?fpr=yangshun) (Free)
## System design
- Design emoji autocomplete.
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete) (Free)
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete?fpr=yangshun) (Free)
- Design JS Bin.
- How would you create a Google Analytics SDK used by webpages?

View File

@ -5,14 +5,14 @@ sidebar_label: LinkedIn interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
## JavaScript
- Write a `getElementsByClassName` function.
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-class-name) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/javascript/get-elements-by-class-name?fpr=yangshun) (Paid)
## User interface coding
@ -22,14 +22,14 @@ Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfro
## Trivia
- Difference between CSS `padding` and `margin`.
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-your-understanding-of-the-box-model-and-how-you-would-tell-the-browser-in-css-to-render-your-layout-in-different-box-models) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-your-understanding-of-the-box-model-and-how-you-would-tell-the-browser-in-css-to-render-your-layout-in-different-box-models?fpr=yangshun) (Free)
- Difference between promise and callback?
- Difference between event bubbling and capturing?
- Difference between callback and closure in JavaScript?
- What are the advantages of using preprocessors? e.g. Sass, Stylus, Less.
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-are-the-advantages-disadvantages-of-using-css-preprocessors) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-are-the-advantages-disadvantages-of-using-css-preprocessors?fpr=yangshun) (Free)
- What is event delegation?
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-event-delegation) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-event-delegation?fpr=yangshun) (Free)
## Algorithm

View File

@ -5,19 +5,19 @@ sidebar_label: Lyft interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
## JavaScript
- Implement `Promise.all`.
- [Practice question](https://www.greatfrontend.com/questions/javascript/promise-all) (Free)
- [Practice question](https://www.greatfrontend.com/questions/javascript/promise-all?fpr=yangshun) (Free)
- Write the logic for minesweeper using vanilla JS.
## User interface coding
- Implement an autocomplete.
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete) (Free)
- [Read answer](https://www.greatfrontend.com/questions/system-design/autocomplete?fpr=yangshun) (Free)
_Source: [Glassdoor Lyft Frontend Engineer Interview Questions](https://www.glassdoor.sg/Interview/Lyft-Frontend-Engineer-Interview-Questions-EI_IE700614.0,4_KO5,22.htm)_

View File

@ -5,14 +5,14 @@ sidebar_label: Microsoft interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
## JavaScript
- Tic-tac-toe implementation using vanilla JavaScript, HTML and CSS.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe?fpr=yangshun) (Paid)
- Create a chat interface like Microsoft teams.
- Use OOP to implement a Chess game.
@ -24,16 +24,16 @@ Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfro
## Trivia
- What is a prototype?
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-how-prototypal-inheritance-works) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/explain-how-prototypal-inheritance-works?fpr=yangshun) (Free)
- What is a closure?
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-a-closure-and-how-why-would-you-use-one) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-a-closure-and-how-why-would-you-use-one?fpr=yangshun) (Free)
- What is the difference between `let`, `const`, and `var`?
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-are-the-differences-between-variables-created-using-let-var-or-const) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-are-the-differences-between-variables-created-using-let-var-or-const?fpr=yangshun) (Free)
- What is DOM?
## System Design
- Design an email client like Microsoft Outlook.
- [Read answer](https://www.greatfrontend.com/questions/system-design/email-client-outlook) (Paid)
- [Read answer](https://www.greatfrontend.com/questions/system-design/email-client-outlook?fpr=yangshun) (Paid)
_Source: [Glassdoor Microsoft Front End Developer Interview Questions](https://www.glassdoor.sg/Interview/Microsoft-Front-End-Developer-Interview-Questions-EI_IE1651.0,9_KO10,29.htm)_

View File

@ -5,7 +5,7 @@ sidebar_label: Salesforce interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -14,15 +14,15 @@ Not much is known about Salesforce's front end interview process.
## Coding
- Flatten a nested array.
- [Practice question](https://www.greatfrontend.com/questions/javascript/flatten) (Free)
- [Practice question](https://www.greatfrontend.com/questions/javascript/flatten?fpr=yangshun) (Free)
## Trivia
- What is the event loop?
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-event-loop-what-is-the-difference-between-call-stack-and-task-queue) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-event-loop-what-is-the-difference-between-call-stack-and-task-queue?fpr=yangshun) (Free)
- What is a closure?
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-a-closure-and-how-why-would-you-use-one) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/what-is-a-closure-and-how-why-would-you-use-one?fpr=yangshun) (Free)
- Positioning in CSS.
- [Read answer](https://www.greatfrontend.com/questions/quiz/whats-the-difference-between-a-relative-fixed-absolute-and-statically-positioned-element) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/whats-the-difference-between-a-relative-fixed-absolute-and-statically-positioned-element?fpr=yangshun) (Free)
_Source: [Glassdoor Salesforce UI Developer Interview Questions](https://www.glassdoor.sg/Interview/Salesforce-UI-Developer-Interview-Questions-EI_IE11159.0,10_KO11,23.htm)_

View File

@ -5,7 +5,7 @@ sidebar_label: Twitter interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -13,11 +13,11 @@ Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfro
- Implement a typeahead. [Source](https://leetcode.com/discuss/interview-question/1220887/Twitter-Frontend-Phone-Screen)
- Add features to a tic-tac-toe game.
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/tic-tac-toe?fpr=yangshun) (Paid)
## Trivia
- What is the difference between `Array.prototype.map` and `Array.prototype.forEach`?
- [Read answer](https://www.greatfrontend.com/questions/quiz/can-you-describe-the-main-difference-between-a-foreach-loop-and-a-map-loop-and-why-you-would-pick-one-versus-the-other) (Free)
- [Read answer](https://www.greatfrontend.com/questions/quiz/can-you-describe-the-main-difference-between-a-foreach-loop-and-a-map-loop-and-why-you-would-pick-one-versus-the-other?fpr=yangshun) (Free)
_Source: [Glassdoor Twitter Front End Developer Interview Questions](https://www.glassdoor.sg/Interview/Twitter-Front-End-Developer-Interview-Questions-EI_IE100569.0,7_KO8,27.htm)_

View File

@ -5,7 +5,7 @@ sidebar_label: Uber interview questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/prepare?fpr=yangshun).
:::
@ -18,5 +18,5 @@ Not much is known about Uber's front end interview process.
## User interface coding
- Create a button that when clicked, adds a progress bar onto the page. The progress bar would then fill up in a given amount of time (think 3 to 5 seconds). If you get past the first part, you will be asked to do throttling how many progress bars can be running at once. For example, if the limit is 3 progress bars, and the user clicks on the button 4 times, the fourth progress bar only starts after the very first one finishes. [Source](https://leetcode.com/discuss/interview-question/1064199/uber-front-end-phone-screen-reject)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/progress-bars) (Paid)
- [Practice question](https://www.greatfrontend.com/questions/user-interface/progress-bars?fpr=yangshun) (Paid)
- Overlapping circles app. [Source](https://leetcode.com/discuss/interview-question/1784074/Uber-or-Phone-or-Overlapping-circles-app-or-Reject)

View File

@ -5,7 +5,7 @@ sidebar_label: CSS questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz?fpr=yangshun).
:::

View File

@ -6,20 +6,20 @@ sidebar_label: Applications
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/system-design/types-of-questions).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/system-design/types-of-questions?fpr=yangshun).
:::
## Examples
- News feed (e.g. Facebook): [Read example solution](https://www.greatfrontend.com/questions/system-design/news-feed-facebook) (Free)
- E-commerce marketplace (e.g. Amazon): [Read example solution](https://www.greatfrontend.com/questions/system-design/e-commerce-amazon) (Paid)
- Chat application (e.g. Messenger): [Read example solution](https://www.greatfrontend.com/questions/system-design/chat-application-messenger) (Paid)
- Photo sharing application (e.g. Instagram): [Read example solution](https://www.greatfrontend.com/questions/system-design/photo-sharing-instagram) (Paid)
- Pinterest: [Read example solution](https://www.greatfrontend.com/questions/system-design/pinterest) (Paid)
- Travel booking website (e.g. Airbnb): [Read example solution](https://www.greatfrontend.com/questions/system-design/travel-booking-airbnb) (Paid)
- Video watching website (e.g. Netflix): [Read example solution](https://www.greatfrontend.com/questions/system-design/video-streaming-netflix) (Paid)
- Email client (e.g. Microsoft Outlook): [Read example solution](https://www.greatfrontend.com/questions/system-design/email-client-outlook) (Paid)
- News feed (e.g. Facebook): [Read example solution](https://www.greatfrontend.com/questions/system-design/news-feed-facebook?fpr=yangshun) (Free)
- E-commerce marketplace (e.g. Amazon): [Read example solution](https://www.greatfrontend.com/questions/system-design/e-commerce-amazon?fpr=yangshun) (Paid)
- Chat application (e.g. Messenger): [Read example solution](https://www.greatfrontend.com/questions/system-design/chat-application-messenger?fpr=yangshun) (Paid)
- Photo sharing application (e.g. Instagram): [Read example solution](https://www.greatfrontend.com/questions/system-design/photo-sharing-instagram?fpr=yangshun) (Paid)
- Pinterest: [Read example solution](https://www.greatfrontend.com/questions/system-design/pinterest?fpr=yangshun) (Paid)
- Travel booking website (e.g. Airbnb): [Read example solution](https://www.greatfrontend.com/questions/system-design/travel-booking-airbnb?fpr=yangshun) (Paid)
- Video watching website (e.g. Netflix): [Read example solution](https://www.greatfrontend.com/questions/system-design/video-streaming-netflix?fpr=yangshun) (Paid)
- Email client (e.g. Microsoft Outlook): [Read example solution](https://www.greatfrontend.com/questions/system-design/email-client-outlook?fpr=yangshun) (Paid)
## Framework
@ -84,4 +84,4 @@ Many companies blog about their technical challenges in the front end domain and
- [A React And Preact Progressive Web App Performance Case Study: Treebo](https://medium.com/dev-channel/treebo-a-react-and-preact-progressive-web-app-performance-case-study-5e4f450d5299)
- [Rebuilding our tech stack for the new Facebook.com](https://engineering.fb.com/2020/05/08/web/facebook-redesign/)
[GreatFrontEnd](https://www.greatfrontend.com/) shows you how to approach front end system design interviews with their [front end system design guide](https://www.greatfrontend.com/system-design) and case studies. You can also do hands-on practice through their [huge question bank](https://www.greatfrontend.com/prepare), each with solutions written by ex-FAANG senior engineers to learn more about system design.
[GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun) shows you how to approach front end system design interviews with their [front end system design guide](https://www.greatfrontend.com/system-design?fpr=yangshun) and case studies. You can also do hands-on practice through their [huge question bank](https://www.greatfrontend.com/prepare?fpr=yangshun), each with solutions written by ex-FAANG senior engineers to learn more about system design.

View File

@ -6,20 +6,20 @@ sidebar_label: UI components
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/system-design/types-of-questions).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/system-design/types-of-questions?fpr=yangshun).
:::
## Examples
- Autocomplete: [Read example solution](https://www.greatfrontend.com/questions/system-design/autocomplete) (Free)
- Image carousel: [Read example solution](https://www.greatfrontend.com/questions/system-design/image-carousel) (Paid)
- Dropdown menu: [Read example solution](https://www.greatfrontend.com/questions/system-design/dropdown-menu) (Paid)
- Modal dialog: [Read example solution](https://www.greatfrontend.com/questions/system-design/modal-dialog) (Paid)
- Poll widget: [Read example solution](https://www.greatfrontend.com/questions/system-design/poll-widget) (Paid)
- Autocomplete: [Read example solution](https://www.greatfrontend.com/questions/system-design/autocomplete?fpr=yangshun) (Free)
- Image carousel: [Read example solution](https://www.greatfrontend.com/questions/system-design/image-carousel?fpr=yangshun) (Paid)
- Dropdown menu: [Read example solution](https://www.greatfrontend.com/questions/system-design/dropdown-menu?fpr=yangshun) (Paid)
- Modal dialog: [Read example solution](https://www.greatfrontend.com/questions/system-design/modal-dialog?fpr=yangshun) (Paid)
- Poll widget: [Read example solution](https://www.greatfrontend.com/questions/system-design/poll-widget?fpr=yangshun) (Paid)
- Selector which loads options over the network
To find out more, check out [GreatFrontEnd](https://www.greatfrontend.com/), which shows you how to approach front end system design interviews with their [front end system design guide](https://www.greatfrontend.com/system-design) and case studies. There are also [blogs](https://www.greatfrontend.com/blog) that will cover some of the following topics in more detail.
To find out more, check out [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun), which shows you how to approach front end system design interviews with their [front end system design guide](https://www.greatfrontend.com/system-design?fpr=yangshun) and case studies. There are also [blogs](https://www.greatfrontend.com/blog?fpr=yangshun) that will cover some of the following topics in more detail.
## Framework

View File

@ -5,7 +5,7 @@ sidebar_label: Overview
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/system-design).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/system-design?fpr=yangshun).
:::
@ -22,20 +22,20 @@ The two main kinds of front end system design interviews are UI components and a
## Front end system design examples
- User interface components
- Autocomplete: [Read example solution](https://www.greatfrontend.com/questions/system-design/autocomplete) (Free)
- Image carousel: [Read example solution](https://www.greatfrontend.com/questions/system-design/image-carousel) (Paid)
- Dropdown menu: [Read example solution](https://www.greatfrontend.com/questions/system-design/dropdown-menu) (Paid)
- Modal dialog: [Read example solution](https://www.greatfrontend.com/questions/system-design/modal-dialog) (Paid)
- Autocomplete: [Read example solution](https://www.greatfrontend.com/questions/system-design/autocomplete?fpr=yangshun) (Free)
- Image carousel: [Read example solution](https://www.greatfrontend.com/questions/system-design/image-carousel?fpr=yangshun) (Paid)
- Dropdown menu: [Read example solution](https://www.greatfrontend.com/questions/system-design/dropdown-menu?fpr=yangshun) (Paid)
- Modal dialog: [Read example solution](https://www.greatfrontend.com/questions/system-design/modal-dialog?fpr=yangshun) (Paid)
- Applications
- News feed (e.g. Facebook): [Read example solution](https://www.greatfrontend.com/questions/system-design/news-feed-facebook) (Free)
- E-commerce marketplace (e.g. Amazon): [Read example solution](https://www.greatfrontend.com/questions/system-design/e-commerce-amazon) (Paid)
- Chat application (e.g. Messenger): [Read example solution](https://www.greatfrontend.com/questions/system-design/chat-application-messenger) (Paid)
- Photo sharing application (e.g. Instagram): [Read example solution](https://www.greatfrontend.com/questions/system-design/photo-sharing-instagram) (Paid)
- Pinterest: [Read example solution](https://www.greatfrontend.com/questions/system-design/pinterest) (Paid)
- Travel booking website (e.g. Airbnb): [Read example solution](https://www.greatfrontend.com/questions/system-design/travel-booking-airbnb) (Paid)
- News feed (e.g. Facebook): [Read example solution](https://www.greatfrontend.com/questions/system-design/news-feed-facebook?fpr=yangshun) (Free)
- E-commerce marketplace (e.g. Amazon): [Read example solution](https://www.greatfrontend.com/questions/system-design/e-commerce-amazon?fpr=yangshun) (Paid)
- Chat application (e.g. Messenger): [Read example solution](https://www.greatfrontend.com/questions/system-design/chat-application-messenger?fpr=yangshun) (Paid)
- Photo sharing application (e.g. Instagram): [Read example solution](https://www.greatfrontend.com/questions/system-design/photo-sharing-instagram?fpr=yangshun) (Paid)
- Pinterest: [Read example solution](https://www.greatfrontend.com/questions/system-design/pinterest?fpr=yangshun) (Paid)
- Travel booking website (e.g. Airbnb): [Read example solution](https://www.greatfrontend.com/questions/system-design/travel-booking-airbnb?fpr=yangshun) (Paid)
- Video watching website
If you are interested to find out more, [GreatFrontEnd](https://www.greatfrontend.com/) shows you how to approach front end system design interviews with their [front end system design guide](https://www.greatfrontend.com/system-design) and case studies.
If you are interested to find out more, [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun) shows you how to approach front end system design interviews with their [front end system design guide](https://www.greatfrontend.com/system-design?fpr=yangshun) and case studies.
## RADIO Framework

View File

@ -5,7 +5,7 @@ sidebar_label: HTML questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz?fpr=yangshun).
:::

View File

@ -4,7 +4,7 @@ title: Introduction
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook?fpr=yangshun).
:::
@ -16,7 +16,7 @@ Many front end interviews are highly-focused on domain knowledge and applying th
While there are some existing resources to help front end developers in preparing for interviews, they aren't as abundant as materials for a general software engineer interview. Among the existing resources, the most helpful question bank would probably be [Front-end Developer Interview Questions](https://github.com/h5bp/Front-end-Developer-Interview-Questions). Unfortunately, there aren't many complete and satisfactory answers to these questions readily available online. This handbook answers these trivia-style questions along with information and guidance for other front end interview formats.
To solve this problem, [GreatFrontEnd](https://www.greatfrontend.com?utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=introduction&fpr=frontendinterviewhandbook), an interview preparation platform for Front End interviews, was created. It contains Front End interview questions and answers written by ex-FAANG Senior Engineers (such as myself!) and have both questions and answers for various formats: JavaScript, TypeScript, User Interface Component questions, quiz-style front end questions.
To solve this problem, [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun), an interview preparation platform for Front End interviews, was created. It contains Front End interview questions and answers written by ex-FAANG Senior Engineers (such as myself!) and have both questions and answers for various formats: JavaScript, TypeScript, User Interface Component questions, quiz-style front end questions.
## General tips for front end interviews
@ -50,7 +50,7 @@ Short questions which test your knowledge and have clear non-subjective answers.
[**Read more about front end trivia questions →**](./trivia.md)
[**Practice front end trivia questions**](https://www.greatfrontend.com/prepare/quiz)
[**Practice front end trivia questions**](https://www.greatfrontend.com/prepare/quiz?fpr=yangshun)
### JavaScript coding
@ -63,7 +63,7 @@ This is the front end version of LeetCode-style algorithm questions. Implement a
[**Read more about JavaScript coding questions →**](./javascript-questions.md)
[**Practice JavaScript coding questions**](https://www.greatfrontend.com/questions/js)
[**Practice JavaScript coding questions**](https://www.greatfrontend.com/questions/js?fpr=yangshun)
### User interface coding
@ -81,7 +81,7 @@ Build user interfaces (can be a UI component, an app, or a game) using HTML, CSS
[**Read more about user interface coding questions →**](./build-front-end-user-interfaces.md)
[**Practice user interface coding questions**](https://www.greatfrontend.com/prepare/coding)
[**Practice user interface coding questions**](https://www.greatfrontend.com/prepare/coding?fpr=yangshun)
### Algorithmic coding
@ -89,7 +89,7 @@ LeetCode-style algorithmic coding questions which evaluate your core data struct
[**Read more about algorithm coding questions →**](./algorithms.md)
[**Practice algorithm questions**](https://www.greatfrontend.com/focus-areas/data-structures-algorithms)
[**Practice algorithm questions**](https://www.greatfrontend.com/focus-areas/data-structures-algorithms?fpr=yangshun)
### System design
@ -100,9 +100,9 @@ Describe and discuss how you would build a UI component/app/game and its archite
[**Read more about front end system design →**](./front-end-system-design.md)
[**Practice front end system design questions**](https://www.greatfrontend.com/prepare/system-design)
[**Practice front end system design questions**](https://www.greatfrontend.com/prepare/system-design?fpr=yangshun)
You can also try out the above mentioned question types at [GreatFrontEnd](https://www.greatfrontend.com). It has [over 200+ practice questions](https://www.greatfrontend.com/prepare) and all of them are provided with comprehensive answers written by ex-FAANG senior engineers.
You can also try out the above mentioned question types at [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun). It has [over 200+ practice questions](https://www.greatfrontend.com/prepare?fpr=yangshun) and all of them are provided with comprehensive answers written by ex-FAANG senior engineers.
## Company interview formats

View File

@ -5,7 +5,7 @@ sidebar_label: JavaScript questions
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz?fpr=yangshun).
:::

View File

@ -6,7 +6,7 @@ sidebar_label: JavaScript coding
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/javascript).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/javascript?fpr=yangshun).
:::
@ -46,13 +46,13 @@ Advanced questions are usually given to more senior candidates and expect around
</video>
</div>
- These questions and many others are available on [GreatFrontEnd](https://www.greatfrontend.com). Apart from a [huge question bank of coding questions](https://www.greatfrontend.com/questions/js/coding/utilities) that you can access by frameworks, each question also comes with a solution authored by ex-FAANG engineers and automated test cases.
- These questions and many others are available on [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun). Apart from a [huge question bank of coding questions](https://www.greatfrontend.com/questions/js/coding/utilities?fpr=yangshun) that you can access by frameworks, each question also comes with a solution authored by ex-FAANG engineers and automated test cases.
- Here are some questions you can start with:
- [Debounce](https://www.greatfrontend.com/questions/javascript/debounce) (Free)
- [Promise.all()](https://www.greatfrontend.com/questions/javascript/promise-all) (Free)
- [Deep Clone](https://www.greatfrontend.com/questions/javascript/deep-clone) (Free)
- [Event Emitter](https://www.greatfrontend.com/questions/javascript/event-emitter) (Free)
- [Array.prototype.filter()](https://www.greatfrontend.com/questions/javascript/array-filter) (Paid)
- [Debounce](https://www.greatfrontend.com/questions/javascript/debounce?fpr=yangshun) (Free)
- [Promise.all()](https://www.greatfrontend.com/questions/javascript/promise-all?fpr=yangshun) (Free)
- [Deep Clone](https://www.greatfrontend.com/questions/javascript/deep-clone?fpr=yangshun) (Free)
- [Event Emitter](https://www.greatfrontend.com/questions/javascript/event-emitter?fpr=yangshun) (Free)
- [Array.prototype.filter()](https://www.greatfrontend.com/questions/javascript/array-filter?fpr=yangshun) (Paid)
## Tips

View File

@ -4,7 +4,7 @@ title: Resume preparation
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/resume).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/resume?fpr=yangshun).
:::

View File

@ -5,7 +5,7 @@ sidebar_label: Overview
:::info We are now part of GreatFrontEnd!
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz).
Front End Interview Handbook is now part of [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun)! We are working to migrate the content over and you may find the latest version of this page on [GreatFrontEnd](https://www.greatfrontend.com/front-end-interview-guidebook/quiz?fpr=yangshun).
:::
@ -35,7 +35,7 @@ The best and correct way to prepare for such questions is to really understand t
## Where to practice
If you're looking for free questions to practice, try [GreatFrontEnd](https://www.greatfrontend.com), which has a [huge bank of free questions](https://www.greatfrontend.com/prepare/quiz). Each question also comes with a solution authored by me.
If you're looking for free questions to practice, try [GreatFrontEnd](https://www.greatfrontend.com?fpr=yangshun), which has a [huge bank of free questions](https://www.greatfrontend.com/prepare/quiz?fpr=yangshun). Each question also comes with a solution authored by me.
## Common questions

View File

@ -11,7 +11,7 @@ Imagine you have an array of numbers, and you want to filter out all the numbers
### Traditional functions syntax
```javascript
```js
const numbers = [1, 5, 10, 15, 20];
const filteredNumbers = numbers.filter(function (number) {
return number >= 10;
@ -22,7 +22,7 @@ console.log(filteredNumbers); // Output: [10, 15, 20]
### Arrow function syntax
```javascript
```js
const numbers = [1, 5, 10, 15, 20];
const filteredNumbers = numbers.filter((number) => number >= 10);

View File

@ -11,7 +11,7 @@ Imagine que você tenha um array de números e queira filtrar todos os números
### Sintaxe de função tradicional
```javascript
```js
const numbers = [1, 5, 10, 15, 20];
const numbersFiltrados = numbers.filter(function (number) {
return number >= 10;
@ -22,7 +22,7 @@ console.log(numbersFiltrados); // Saída: [10, 15, 20]
### Sintaxe de função de seta
```javascript
```js
const numbers = [1, 5, 10, 15, 20];
const numbersFiltrados = numbers.filter((number) => number >= 10);

View File

@ -4,18 +4,18 @@ title: Describe event bubbling
## TL;DR
**Event bubbling** is a DOM event propagation mechanism where an event, like a click, starts at the target element and bubbles up to the root of the document. This allows ancestor elements to also respond to the event.
Event bubbling is a DOM event propagation mechanism where an event (e.g. a click), starts at the target element and bubbles up to the root of the document. This allows ancestor elements to also respond to the event.
**Practical Use:** Event bubbling is essential for event delegation, where a single event handler manages events for multiple child elements, enhancing performance and code simplicity.
**Pitfall:** Failing to manage event propagation can lead to unintended behavior, such as multiple handlers firing for a single event.
Event bubbling is essential for event delegation, where a single event handler manages events for multiple child elements, enhancing performance and code simplicity. While convenient, failing to manage event propagation properly can lead to unintended behavior, such as multiple handlers firing for a single event.
---
## What is Event Bubbling?
## What is event bubbling?
Event bubbling is a propagation mechanism in the DOM (Document Object Model) where an event, such as a click or a keyboard event, is first triggered on the target element that initiated the event and then propagates upward (bubbles) through the DOM tree to the root of the document.
**Note**: even before the event bubbling phase happens is the [event capturing](/questions/quiz/describe-event-capturing) phase which is the opposite of bubbling where the event goes down from the document root to the target element.
## Bubbling phase
During the bubbling phase, the event starts at the target element and bubbles up through its ancestors in the DOM hierarchy. This means that the event handlers attached to the target element and its ancestors can all potentially receive and respond to the event.
@ -42,9 +42,9 @@ child.addEventListener('click', () => {
When you click the "Click me!" button, both the child and parent event handlers will be triggered due to the event bubbling.
## Stopping propagation
## Stopping the bubbling
Event propagation can be stopped during the bubbling phase using the `stopPropagation()` method. If an event handler calls `stopPropagation()`, it prevents the event from further bubbling up the DOM tree, ensuring that only the handlers of the elements up to that point in the hierarchy are executed.
Event bubbling can be stopped during the bubbling phase using the `stopPropagation()` method. If an event handler calls `stopPropagation()`, it prevents the event from further bubbling up the DOM tree, ensuring that only the handlers of the elements up to that point in the hierarchy are executed.
```js
child.addEventListener('click', (event) => {
@ -55,7 +55,8 @@ child.addEventListener('click', (event) => {
## Event delegation
Event bubbling is the basis for a technique called "event delegation", where you attach a single event handler to a common ancestor of multiple elements and use event delegation to handle events for those elements efficiently. This is particularly useful when you have a large number of similar elements, like a list of items, and you want to avoid attaching individual event handlers to each item.
Event bubbling is the basis for a technique called [event delegation](/questions/quiz/describe-event-delegation), where you attach a single event handler to a common ancestor of multiple elements and use event delegation to handle events for those elements efficiently. This is particularly useful when you have a large number of similar elements, like a list of items, and you want to avoid attaching individual event handlers to each item.
```js
parent.addEventListener('click', (event) => {
if (event.target && event.target.id === 'child') {
@ -66,21 +67,21 @@ parent.addEventListener('click', (event) => {
## Benefits
- **Cleaner Code:** Reduced number of event listeners improves code readability and maintainability.
- **Efficient Event Handling:** Minimizes performance overhead by attaching fewer listeners.
- **Cleaner code:** Reduced number of event listeners improves code readability and maintainability.
- **Efficient event handling:** Minimizes performance overhead by attaching fewer listeners.
- **Flexibility:** Allows handling events happening on child elements without directly attaching listeners to them.
## Pitfalls
- **Accidental Event Handling:** Be mindful that parent elements might unintentionally capture events meant for children. Use `event.target` to identify the specific element that triggered the event.
- **Event Order:** Events bubble up in a specific order. If multiple parents have event listeners, their order of execution depends on the DOM hierarchy.
- **Accidental event handling:** Be mindful that parent elements might unintentionally capture events meant for children. Use `event.target` to identify the specific element that triggered the event.
- **Event order:** Events bubble up in a specific order. If multiple parents have event listeners, their order of execution depends on the DOM hierarchy.
- **Over-delegation:** While delegating events to a common ancestor is efficient, attaching a listener too high in the DOM tree might capture unintended events.
## Use Cases
## Use cases
Here are some of the practical use cases with code examples.
Here are some practical ways to use event bubbling to write better code.
### Reducing Code with Event Delegation
### Reducing code with event delegation
Imagine you have a product list with numerous items, each with a "Buy Now" button. Traditionally, you might attach a separate click event listener to each button:
@ -91,16 +92,16 @@ Imagine you have a product list with numerous items, each with a "Buy Now" butto
// <li><button id="item2-buy">Buy Now</button></li>
// </ul>
const item1Buy = document.getElementById("item1-buy");
const item2Buy = document.getElementById("item2-buy");
const item1Buy = document.getElementById('item1-buy');
const item2Buy = document.getElementById('item2-buy');
item1Buy.addEventListener("click", handleBuyClick);
item2Buy.addEventListener("click", handleBuyClick);
item1Buy.addEventListener('click', handleBuyClick);
item2Buy.addEventListener('click', handleBuyClick);
// ... repeat for each item ...
function handleBuyClick(event) {
console.log("Buy button clicked for item:", event.target.id);
console.log('Buy button clicked for item:', event.target.id);
}
```
@ -113,51 +114,50 @@ This approach becomes cumbersome as the number of items grows. Here's how event
// <li><button id="item2-buy">Buy Now</button></li>
// </ul>
const productList = document.getElementById("product-list");
const productList = document.getElementById('product-list');
productList.addEventListener("click", handleBuyClick);
productList.addEventListener('click', handleBuyClick);
function handleBuyClick(event) {
// Check if the clicked element is a button within the list
if (event.target.tagName.toLowerCase() === "button") {
console.log("Buy button clicked for item:", event.target.textContent);
if (event.target.tagName.toLowerCase() === 'button') {
console.log('Buy button clicked for item:', event.target.textContent);
}
}
```
By attaching the listener to the parent (`productList`) and checking the clicked element (`event.target`) within the handler, you achieve the same functionality with less code. This approach scales efficiently as you add more items.
By attaching the listener to the parent (`productList`) and checking the clicked element (`event.target`) within the handler, you achieve the same functionality with less code. This approach scales well when the items are dynamic as no new event handlers have to be added or removed when the list of items change.
### Dropdown Menus
### Dropdown menus
Consider a dropdown menu where clicking anywhere on the menu element (parent) should close it. With event bubbling, you can achieve this with a single listener:
```js
// HTML:
// <div id="dropdown">
// <button>Open Menu</button>
// <button>Open Menu</button>
// <ul>
// <li>Item 1</li>
// <li>Item 2</li>
// <li>Item 1</li>
// <li>Item 2</li>
// </ul>
// </div>
const dropdown = document.getElementById("dropdown");
const dropdown = document.getElementById('dropdown');
dropdown.addEventListener("click", handleDropdownClick);
dropdown.addEventListener('click', handleDropdownClick);
function handleDropdownClick(event) {
// Close the dropdown if clicked outside the button
if (event.target !== dropdown.querySelector("button")) {
console.log("Dropdown closed");
if (event.target !== dropdown.querySelector('button')) {
console.log('Dropdown closed');
// Your logic to hide the dropdown content
}
}
```
Here, the click event bubbles up from the clicked element (button or list item) to the `dropdown` element. The handler checks if the clicked element is not the button and closes the menu accordingly.
Here, the click event bubbles up from the clicked element (button or list item) to the `dropdown` element. The handler checks if the clicked element is not the `<button>` and closes the menu accordingly.
### Accordion Menus
### Accordion menus
Imagine an accordion menu where clicking a section header (parent) expands or collapses the content section (child) below it. Event bubbling makes this straightforward:
@ -170,15 +170,15 @@ Imagine an accordion menu where clicking a section header (parent) expands or co
// <div class="content">Content for Section 2</div>
// </div>
const accordion = document.querySelector(".accordion");
const accordion = document.querySelector('.accordion');
accordion.addEventListener("click", handleAccordionClick);
accordion.addEventListener('click', handleAccordionClick);
function handleAccordionClick(event) {
// Check if clicked element is a header
if (event.target.classList.contains("header")) {
if (event.target.classList.contains('header')) {
const content = event.target.nextElementSibling;
content.classList.toggle("active"); // Toggle display of content
content.classList.toggle('active'); // Toggle display of content
}
}
```
@ -190,4 +190,3 @@ By attaching the listener to the `accordion` element, clicking on any header tri
- [MDN Web Docs on Event Bubbling](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling)
- [JavaScript.info - Bubbling and Capturing](https://javascript.info/bubbling-and-capturing)
- [W3C DOM Level 3 Events Specification](https://www.w3.org/TR/DOM-Level-3-Events/#event-flow)

View File

@ -4,25 +4,29 @@ title: Describe event capturing
**TL;DR**
Event capturing is a lesser-used counterpart to event bubbling in the DOM event propagation mechanism. It follows the opposite order, where an event triggers first on the ancestor element and then travels down to the target element. Event capturing is rarely used as compared to Event bubbling, but it can be used in specific scenarios where you need to intercept events at a higher level before they reach the target element.
Event capturing is a lesser-used counterpart to [event bubbling](/questions/quiz/describe-event-bubbling) in the DOM event propagation mechanism. It follows the opposite order, where an event triggers first on the ancestor element and then travels down to the target element.
Event capturing is rarely used as compared to event bubbling, but it can be used in specific scenarios where you need to intercept events at a higher level before they reach the target element. It is disabled by default but can be enabled through an option on `addEventListener()`.
---
## What is Event capturing?
## What is event capturing?
Event capturing is a propagation mechanism in the DOM (Document Object Model) where an event, such as a click or a keyboard event, is first triggered at the root of the document and then flows down through the DOM tree to the target element.
Capturing has a higher priority than bubbling, meaning that capturing event handlers are executed before bubbling event handlers, as shown by the phases of event propagation:
- Capturing phase: The event moves down towards the target element
- Target phase: The event reaches the target element
- Bubbling phase: The event bubbles up from the target element
- **Capturing phase**: The event moves down towards the target element
- **Target phase**: The event reaches the target element
- **Bubbling phase**: The event bubbles up from the target element
Note that event capturing is disabled by default. To enable it you have to pass the capture option into `addEventListener()`.
## Capturing phase
During the capturing phase, the event starts at the document root and propagates down to the target element. Any event listeners on ancestor elements in this path will be triggered before the target element's handler. But note that event capturing can't happen until the third argument of `addEventListener()` is set to the `Boolean` value of `true` as shown below (default value is `false`).
During the capturing phase, the event starts at the document root and propagates down to the target element. Any event listeners on ancestor elements in this path will be triggered before the target element's handler. But note that event capturing can't happen until the third argument of `addEventListener()` is set to `true` as shown below (default value is `false`).
Here's an example using modern ES6 syntax to demonstrate event capturing:
Here's an example using modern ES2015 syntax to demonstrate event capturing:
```js
// HTML:
@ -38,8 +42,8 @@ parent.addEventListener(
() => {
console.log('Parent element clicked (capturing)');
},
true,
); // Set third argument to true for capturing
true, // Set third argument to true for capturing
);
child.addEventListener('click', () => {
console.log('Child element clicked');
@ -75,9 +79,15 @@ child.addEventListener('click', () => {
});
```
Now, as a result of stopping event propagation, just the `parent` event listener will now be called when you click the "Click Me!" button, and the `child` event listener will never be called because the event propagation has stopped at the `parent` element.
As a result of stopping event propagation, just the `parent` event listener will now be called when you click the "Click Me!" button, and the `child` event listener will never be called because the event propagation has stopped at the `parent` element.
Event capturing is rarely used as compared to Event bubbling, but it can be used in specific scenarios where you need to intercept events at a higher level before they reach the target element.
## Uses of event capturing
Event capturing is rarely used as compared to event bubbling, but it can be used in specific scenarios where you need to intercept events at a higher level before they reach the target element.
- **Stopping event bubbling:** Imagine you have a nested element (like a button) inside a container element. Clicking the button might also trigger a click event on the container. By using enabling event capturing on the container's event listener, you can capture the click event there and prevent it from traveling down to the button, potentially causing unintended behavior.
- **Custom dropdown menus:**: When building custom dropdown menus, you might want to capture clicks outside the menu element to close the menu. Using `capture: true` on the `document` object allows you to listen for clicks anywhere on the page and close the menu if the click happens outside its boundaries.
- **Efficiency in certain scenarios:**: In some situations, event capturing can be slightly more efficient than relying on bubbling. This is because the event doesn't need to propagate through all child elements before reaching the handler. However, the performance difference is usually negligible for most web applications.
## Further reading

View File

@ -1,19 +1,19 @@
---
title: 'Difference between: `function Person(){}`, `var person = Person()`, and `var person = new Person()`?'
title: 'Difference between: `function Person(){}`, `const person = Person()`, and `const person = new Person()`?'
---
## TL;DR
- `function Person(){}`: A function declaration in JavaScript. It can be used as a regular function or as a constructor.
- `var person = Person()`: Calls `Person` as a regular function, not a constructor. If Person is intended to be a constructor, this will lead to unexpected behavior.
- `var person = new Person()`: Creates a new instance of `Person`, correctly utilizing the constructor function to initialize the new object.
- `const person = Person()`: Calls `Person` as a regular function, not a constructor. If `Person` is intended to be a constructor, this will lead to unexpected behavior.
- `const person = new Person()`: Creates a new instance of `Person`, correctly utilizing the constructor function to initialize the new object.
| Aspect | `function Person(){}` | `var person = Person()` | `var person = new Person()` |
|------------------|-----------------------|---------------------------------------------|-----------------------------------|
| Type | Function declaration | Function call | Constructor call |
| Usage | Defines a function | Invokes `Person` as a regular function | Creates a new instance of `Person`|
| Instance Creation| No instance created | No instance created | New instance created |
| Common Mistake | N/A | Misusing as constructor leading to undefined| None (when used correctly) |
| Aspect | `function Person(){}` | `const person = Person()` | `const person = new Person()` |
| --- | --- | --- | --- |
| Type | Function declaration | Function call | Constructor call |
| Usage | Defines a function | Invokes `Person` as a regular function | Creates a new instance of `Person` |
| Instance Creation | No instance created | No instance created | New instance created |
| Common Mistake | N/A | Misusing as constructor leading to `undefined` | None (when used correctly) |
---
@ -26,50 +26,54 @@ function Person(name) {
this.name = name;
}
```
This code defines a function named `Person` that takes a parameter `name` and assigns it to the `name` property of the object created from this constructor function. When the `this` keyword is used in a constructor, it refers to the newly created object.
## Function call
`var person = Person()` simply invoke the function's code. When you invoke `Person` as a regular function (i.e., without the `new` keyword), the function does not behave as a constructor. Instead, it executes its code and returns `undefined` if no return value is specified and that gets assigned to the variable intended as the instance. Invoking as such is a common mistake if the function is intended to be used as a constructor.
`const person = Person()` simply invoke the function's code. When you invoke `Person` as a regular function (i.e., without the `new` keyword), the function does not behave as a constructor. Instead, it executes its code and returns `undefined` if no return value is specified and that gets assigned to the variable intended as the instance. Invoking as such is a common mistake if the function is intended to be used as a constructor.
```js
function Person(name) {
this.name = name;
}
var person = Person('John');
const person = Person('John');
console.log(person); // undefined
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined
```
In this case, `Person('John')` does not create a new object. The `person` variable is assigned `undefined` because the `Person` function does not explicitly return a value. Attempting to access `person.name` throws an error because `person` is `undefined`.
## Constructor call
## Constructor call
`var person = new Person()` creates an instance of the `Person` object using the new operator, which inherits from `Person.prototype`. An alternative would be to use `Object.create`, such as: `Object.create(Person.prototype)` and `Person.call(person, 'John')` initializes the object.
`const person = new Person()` creates an instance of the `Person` object using the new operator, which inherits from `Person.prototype`. An alternative would be to use `Object.create`, such as: `Object.create(Person.prototype)` and `Person.call(person, 'John')` initializes the object.
```js
function Person(name) {
this.name = name;
}
var person = new Person('John');
const person = new Person('John');
console.log(person); // Person { name: 'John' }
console.log(person.name); // 'John'
// Alternative
var person1 = Object.create(Person.prototype);
const person1 = Object.create(Person.prototype);
Person.call(person1, 'John');
console.log(person1); // Person { name: 'John' }
console.log(person1.name); // 'John'
```
In this case, `new Person('John')` creates a new object, and `this` within `Person` refers to this new object. The `name` property is correctly set on the new object. The `person` variable is assigned the new instance of `Person` with the name property set to `'John'`. And for the alternative object creation, `Object.create(Person.prototype)` creates a new object with `Person.prototype` as its prototype. `Person.call(person, 'John')` initializes the object, setting the `name` property.
In this case, `new Person('John')` creates a new object, and `this` within `Person` refers to this new object. The `name` property is correctly set on the new object. The `person` variable is assigned the new instance of `Person` with the name property set to `'John'`. And for the alternative object creation, `Object.create(Person.prototype)` creates a new object with `Person.prototype` as its prototype. `Person.call(person, 'John')` initializes the object, setting the `name` property.
## Follow-Up Questions
- What are the differences between function constructors and ES6 class syntax?
- What are some common use cases for Object.create?
- What are some common use cases for `Object.create`?
## Further reading
- [MDN Web Docs: Object prototypes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes)
- [Differences between Class and Function Constructors](https://www.greatfrontend.com/questions/quiz/what-are-the-differences-between-es6-class-and-es5-function-constructors)
- [How `this` keyword works in JavaScript?](https://www.greatfrontend.com/questions/quiz/explain-how-this-works-in-javascript)
- [Differences between Class and Function Constructors](https://www.greatfrontend.com/questions/quiz/what-are-the-differences-between-es6-class-and-es5-function-constructors?fpr=yangshun)
- [How `this` keyword works in JavaScript?](https://www.greatfrontend.com/questions/quiz/explain-how-this-works-in-javascript?fpr=yangshun)

View File

@ -3,18 +3,27 @@ title: Explain event delegation
---
## TL;DR
**Event delegation** is a JavaScript design pattern where a single event listener is attached to a common ancestor to manage events for multiple child elements efficiently.
**Practical Use:** It's essential for handling events on dynamic or numerous elements, such as list items, without attaching individual listeners to each.
Event delegation is a technique in JavaScript where a single event listener is attached to a parent element instead of attaching event listeners to multiple child elements. When an event occurs on a child element, the event bubbles up the DOM tree, and the parent element's event listener handles the event based on the target element.
**Benefit:** Event delegation improves performance, reduces memory usage, and simplifies code maintenance.
Event delegation provides the following benefits:
**Pitfall:** Incorrectly identifying the event target can lead to unintended behavior.
- **Improved performance**: Attaching a single event listener is more efficient than attaching multiple event listeners to individual elements, especially for large or dynamic lists. This reduces memory usage and improves overall performance.
- **Simplified event handling**: With event delegation, you only need to write the event handling logic once in the parent element's event listener. This makes the code more maintainable and easier to update.
- **Dynamic element support**: Event delegation automatically handles events for dynamically added or removed elements within the parent element. There's no need to manually attach or remove event listeners when the DOM structure changes
However, do note that:
- It is important to identify the target element that triggered the event.
- Not all events can be delegated because they are not bubbled. Non-bubbling events include: `focus`, `blur`, `scroll`, `mouseenter`, `mouseleave`, `resize`, etc.
---
Event delegation is a design pattern in JavaScript used to efficiently manage and handle events on multiple child elements by attaching a single event listener to a common ancestor element. This pattern is particularly valuable in scenarios where you have a large number of similar elements, such as list items, and want to streamline event handling.
## How Event Delegation works
## Event delegation
Event delegation is a design pattern in JavaScript used to efficiently manage and handle events on multiple child elements by attaching a single event listener to a common ancestor element. This pattern is particularly valuable in scenarios where you have a large number of similar elements, such as list items, and want to optimize event handling.
## How event delegation works
1. **Attach a listener to a common ancestor**: Instead of attaching individual event listeners to each child element, you attach a single event listener to a common ancestor element higher in the DOM hierarchy.
1. **Event bubbling**: When an event occurs on a child element, it bubbles up through the DOM tree to the common ancestor element. During this propagation, the event listener on the common ancestor can intercept and handle the event.
@ -28,7 +37,7 @@ Event delegation is a design pattern in JavaScript used to efficiently manage an
## Example
Here's a simple example using modern ES6 syntax:
Here's a simple example:
```js
// HTML:
@ -47,34 +56,14 @@ itemList.addEventListener('click', (event) => {
});
```
In this example, a single click event listener is attached to the `<ul>` element. When a click event occurs on an `<li>` element, the event bubbles up to the `<ul>` element, where the event listener checks the target's tag name to identify which list item was clicked.
In this example, a single click event listener is attached to the `<ul>` element. When a click event occurs on an `<li>` element, the event bubbles up to the `<ul>` element, where the event listener checks the target's tag name to identify whether a list item was clicked. It's crucial to check the identity of the `event.target` as there can be other kinds of elements in the DOM tree.
## Use Cases
## Use cases
Event delegation is commonly used in scenarios like:
### Managing lists, menus, or tables with many items or rows
```js
// HTML:
// <ul id="item-list">
// <li>Item 1</li>
// <li>Item 2</li>
// <li>Item 3</li>
// </ul>
const itemList = document.getElementById('item-list');
itemList.addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
console.log(`Clicked on ${event.target.textContent}`);
}
});
```
In this example, a single click event listener is attached to the `<ul>` element. When a click event occurs on an `<li>` element, the event bubbles up to the `<ul>` element, where the event listener checks the target's tag name to identify which list item was clicked.
### Handling dynamic content in single-page applications
```js
// HTML:
// <div id="button-container">
@ -99,7 +88,7 @@ addButton.addEventListener('click', () => {
});
```
In this example, a click event listener is attached to the `<div>` container. When a new button is added dynamically and clicked, the event listener on the container handles the click event.
In this example, a `click` event listener is attached to the `<div>` container. When a new button is added dynamically and clicked, the event listener on the container handles the click event.
### Simplifying code by avoiding the need to attach and remove event listeners for elements that change
@ -119,14 +108,26 @@ userForm.addEventListener('input', (event) => {
});
```
In this example, a single input event listener is attached to the form element. It handles input changes for all child input elements, simplifying the code by avoiding multiple event listeners.
In this example, a single input event listener is attached to the form element. It can respond to input changes for all child input elements, simplifying the code by an event listeners per `<input>` element.
## Pitfalls
- **Incorrect Target Handling:** Ensure correct identification of the event target to avoid unintended actions.
- **Event Overhead:** While event delegation is efficient, handling complex logic within the event listener can introduce overhead if not managed properly.
Do note that event delegation come with certain pitfalls:
- **Incorrect target handling:** Ensure correct identification of the event target to avoid unintended actions.
- **Not all events can be delegated/bubbled**: Not all events can be delegated because they are not bubbled. Non-bubbling events include: `focus`, `blur`, `scroll`, `mouseenter`, `mouseleave`, `resize`, etc.
- **Event overhead:** While event delegation is generally more efficient, there needs to be complex logic written within the root event listener to identify the triggering element and respond appropriately. This can introduce overhead and can be potentially more complex if not managed properly.
## Event delegation in JavaScript frameworks
In [React](https://react.dev/), event handlers are attached to the React root's DOM container into which the React tree is rendered. Even though `onClick` is added to child elements, the actual event listeners are attached to the root DOM node, leveraging event delegation to optimize event handling and improve performance.
When an event occurs, React's event listener captures it and determines which React component rendered the target element based on its internal bookkeeping. React then dispatches the event to the appropriate component's event handler by calling the handler function with a synthetic event object. This synthetic event object wraps the native browser event, providing a consistent interface across different browsers and capturing information about the event.
By using event delegation, React avoids attaching individual event handlers to each component instance, which would create significant overhead, especially for large component trees. Instead, React leverages the browser's native event bubbling mechanism to capture events at the root and distribute them to the appropriate components.
## Further reading
- [MDN Web Docs on Event Delegation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_delegation)
- [JavaScript.info - Event Delegation](https://javascript.info/event-delegation)
- [React v17.0 Release Candidate: No New Features](https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#changes-to-event-delegation)

View File

@ -14,7 +14,7 @@ A delegação de eventos é um conceito fundamental no desenvolvimento web que p
Vamos ilustrar a delegação de eventos com um exemplo moderno usando a sintaxe do ES6:
```javascript
```js
// HTML:
// <ul id="item-list">
// <li>Item 1</li>

View File

@ -4,13 +4,21 @@ title: Explain `Function.prototype.bind`
## TL;DR
> The `bind()` method creates a new function that, when called, has its `this` keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
`Function.prototype.bind` is a method in JavaScript that allows you to create a new function with a specific `this` value and optional initial arguments. It's primary purpose is to:
_Source: [Function.prototype.bind() - JavaScript | MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind)_
- **Binding `this` value to preserve context**: The primary purpose of `bind` is to bind the `this` value of a function to a specific object. When you call `func.bind(thisArg)`, it creates a new function with the same body as `func`, but with `this` permanently bound to `thisArg`.
- **Partial application of arguments**: `bind` also allows you to pre-specify arguments for the new function. Any arguments passed to `bind` after `thisArg` will be prepended to the arguments list when the new function is called.
- **Method borrowing**: `bind` allows you to borrow methods from one object and apply them to another object, even if they were not originally designed to work with that object.
The `bind` method is particularly useful in scenarios where you need to ensure that a function is called with a specific `this` context, such as in event handlers, callbacks, or method borrowing.
---
`Function.prototype.bind` allows you to create a new function with a specific `this` context and, optionally, preset arguments. `bind()` is most useful for binding the value of `this` in methods of classes that you want to pass into other functions. This was frequently done in React class component methods which were not defined using arrow functions.
## `Function.prototype.bind`
`Function.prototype.bind` allows you to create a new function with a specific `this` context and, optionally, preset arguments. `bind()` is most useful for preserving the value of `this` in methods of classes that you want to pass into other functions.
`bind` was frequently used on legacy React class component methods which were not defined using arrow functions.
```js
const john = {
@ -37,43 +45,52 @@ In the example above, when the `getAge` method is called without a calling objec
We can even use `getAge` on another object which is not `john`! `boundGetAgeMary` returns the `age` of `mary`.
## Use Cases
## Use cases
### Fixing the `this` value in callbacks
Here are some common scenarios where `bind` is frequently used:
When you pass a function as a callback, the `this` value inside the function can be unpredictable. Using `bind()` helps ensure that the correct `this` value is maintained.
### Preserving context and fixing the `this` value in callbacks
When you pass a function as a callback, the `this` value inside the function can be unpredictable because it is determined by the execution context. Using `bind()` helps ensure that the correct `this` value is maintained.
```js
const person = {
name: 'John Doe',
greet: function () {
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
},
};
const john = new Person('John Doe');
// Without bind(), `this` inside the callback will be the global object
setTimeout(person.greet, 1000); // Output: "Hello, my name is undefined"
setTimeout(john.greet, 1000); // Output: "Hello, my name is undefined"
// Using bind() to fix the `this` value
setTimeout(person.greet.bind(person), 1000); // Output: "Hello, my name is John Doe"
setTimeout(john.greet.bind(john), 2000); // Output: "Hello, my name is John Doe"
```
You can also use [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) for this purpose instead of `bind`.
You can also use [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) to define class methods for this purpose instead of using `bind`. Arrow functions have the `this` value bound to its lexical context.
```js
const person = {
name: 'John Doe',
greet: function () {
class Person {
constructor(name) {
this.name = name;
}
greet = () => {
console.log(`Hello, my name is ${this.name}`);
},
};
};
}
setTimeout(() => person.greet(), 1000); // Output: "Hello, my name is John Doe"
const john = new Person('John Doe');
setTimeout(john.greet, 1000); // Output: "Hello, my name is John Doe"
```
### Partial application of functions (currying)
`bind()` can be used to create a new function with some arguments pre-set. This is known as partial application or currying.
`bind` can be used to create a new function with some arguments pre-set. This is known as partial application or currying.
```js
function multiply(a, b) {
@ -85,27 +102,20 @@ const multiplyBy5 = multiply.bind(null, 5);
console.log(multiplyBy5(3)); // Output: 15
```
### Converting instance methods to standalone functions
### Method borrowing
When you need to use an instance method as a standalone function, `bind()` can help.
`bind` allows you to borrow methods from one object and apply them to another object, even if they were not originally designed to work with that object. This can be handy when you need to reuse functionality across different objects
```js
class Person {
constructor(name) {
this.name = name;
}
const person = {
name: 'John',
greet: function () {
console.log(`Hello, ${this.name}!`);
},
};
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
const john = new Person('John');
john.greet(); // Output: "Hello, my name is John"
// Converting the instance method to a standalone function using bind()
const johnGreet = john.greet.bind(john);
johnGreet(); // Output: "Hello, my name is John"
const greetPerson = person.greet.bind({ name: 'Alice' });
greetPerson(); // Output: Hello, Alice!
```
## Practice

View File

@ -136,3 +136,4 @@ ESLint is a static code analyzer that can find violations of such cases with the
## Further reading
- [Hoisting | MDN](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
- [JavaScript Visualized: Hoisting](https://dev.to/lydiahallie/javascript-visualized-hoisting-478h)

View File

@ -43,8 +43,8 @@ bolt.bark(); // "Woof!"
Things to note are:
- `.makeSound` is not defined on `Dog`, so the engine goes up the prototype chain and finds `.makeSound` off the inherited `Animal`.
- Using `Object.create` to build the inheritance chain is no longer recommended. Use `Object.setPrototypeOf` instead.
- `.makeSound` is not defined on `Dog`, so the JavaScript engine goes up the prototype chain and finds `.makeSound` on the inherited `Animal`.
- Using `Object.create()` to build the inheritance chain is no longer recommended. Use `Object.setPrototypeOf()` instead.
---
@ -96,9 +96,9 @@ john.sayGoodbye(); // "Goodbye, my name is John"
console.log(john.sayHello); // undefined
```
2. **Prototype Chain**: When a property or method is accessed on an object, JavaScript first looks for it on the object itself. If it doesn't find it there, it looks at the object's prototype, and then the prototype's prototype, and so on, until it either finds the property or reaches the end of the chain (i.e., null).
2. **Prototype chain**: When a property or method is accessed on an object, JavaScript first looks for it on the object itself. If it doesn't find it there, it looks at the object's prototype, and then the prototype's prototype, and so on, until it either finds the property or reaches the end of the chain (i.e., `null`).
3. **Constructor Functions**: JavaScript provides constructor functions to create objects. When a function is used as a constructor with the new keyword, the new objects prototype ([[Prototype]]) is set to the constructors prototype property.
3. **Constructor functions**: JavaScript provides constructor functions to create objects. When a function is used as a constructor with the new keyword, the new object's prototype (`[[Prototype]]`) is set to the constructor's prototype property.
```js
// Define a constructor function
@ -136,7 +136,7 @@ fido.sayName(); // "My name is Fido"
console.log(fido.fly); // undefined
```
4. **Object.create()**: This method creates a new object with the specified prototype object and properties. It's a straightforward way to set up prototypical inheritance. If you create a object via `Object.create(null)` it will not inherit any properties from `Object.prototype`. This means the object will not have any built-in properties or methods like `toString()`, `hasOwnProperty()`,
4. **`Object.create()`**: This method creates a new object with the specified prototype object and properties. It's a straightforward way to set up prototypical inheritance. If you create a object via `Object.create(null)` it will not inherit any properties from `Object.prototype`. This means the object will not have any built-in properties or methods like `toString()`, `hasOwnProperty()`,
```js
// Define a prototype object
@ -175,3 +175,4 @@ animal.describe(); // "Name of the animal is Rocky"
## Resources
- [Inheritance and the prototype chain | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)
- [JavaScript Visualized: Prototypal Inheritance](https://dev.to/lydiahallie/javascript-visualized-prototypal-inheritance-47co)

View File

@ -4,22 +4,22 @@ title: Explain the difference between mutable and immutable objects
## TL;DR
- **Mutable Objects**: Allow for modification of properties and values after creation. (Default behavior for most objects)
**Mutable objects** allow for modification of properties and values after creation, which is the default behavior for most objects.
```js
const immutableObject = Object.freeze({
const mutableObject = {
name: 'John',
age: 30,
});
};
// Attempt to modify the object
immutableObject.name = 'Jane';
// Modify the object
mutableObject.name = 'Jane';
// The object remains unchanged
console.log(immutableObject); // Output: { name: 'John', age: 30 }
// The object has been modified
console.log(mutableObject); // Output: { name: 'Jane', age: 30 }
```
- **Immutable Objects**: Cannot be directly modified after creation. Its content cannot be changed without creating an entirely new value.
**Immutable objects** cannot be directly modified after creation. Its content cannot be changed without creating an entirely new value.
```js
const immutableObject = Object.freeze({
@ -38,13 +38,13 @@ The key difference between mutable and immutable objects is modifiability. Immut
---
Immutability is a core principle in functional programming and has lots to offer to object-oriented programs as well.
## Immutability
## Mutable Objects
Immutability is a core principle in functional programming but it has lots to offer to object-oriented programs as well.
Mutability refers to the ability of an object to have its properties or elements changed after it's created. . A mutable object is an object whose state can be modified after it is created. In JavaScript, objects and arrays are mutable by default. They store references to their data in memory. Changing a property or element modifies the original object.
### Mutable objects
Here is an example of a mutable object:
Mutability refers to the ability of an object to have its properties or elements changed after it's created. A mutable object is an object whose state can be modified after it is created. In JavaScript, objects and arrays are mutable by default. They store references to their data in memory. Changing a property or element modifies the original object. Here is an example of a mutable object:
```js
const mutableObject = {
@ -59,11 +59,9 @@ mutableObject.name = 'Jane';
console.log(mutableObject); // Output: { name: 'Jane', age: 30 }
```
## Immutable Objects
### Immutable objects
An immutable object is an object whose state cannot be modified after it is created.
Here is an example of an immutable object:
An immutable object is an object whose state cannot be modified after it is created. Here is an example of an immutable object:
```js
const immutableObject = Object.freeze({
@ -78,7 +76,7 @@ immutableObject.name = 'Jane';
console.log(immutableObject); // Output: { name: 'John', age: 30 }
```
Primitive data types like numbers, strings, booleans, null, and undefined are inherently immutable. Once assigned a value, you cannot directly modify them. Here's an example:
Primitive data types like numbers, strings, booleans, `null`, and `undefined` are inherently immutable. Once assigned a value, you cannot directly modify them.
```js
let name = 'Alice';
@ -90,20 +88,47 @@ name = name.toUpperCase();
console.log(name); // Now prints "ALICE"
```
### What is an example of an immutable object in JavaScript?
Some built-in immutable JavaScript objects are `Math`, `Date` but custom objects are generally mutable.
In JavaScript, some built-in types (numbers, strings) are immutable, but custom objects are generally mutable.
### `const` vs immutable objects
Some built-in immutable JavaScript objects are `Math`, `Date`.
A common confusion / misunderstanding is that declaring a variable using `const` makes the value immutable, which is not true at all.
Here are a few ways to add/simulate immutability on plain JavaScript objects.
`const` prevents reassignment of the variable itself, but does not make the value it holds immutable. This means:
#### Object Constant Properties
- For primitive values (numbers, strings, booleans), `const` makes the value immutable since primitives are immutable by nature.
- For non-primitive values like objects and arrays, `const` only prevents reassigning a new object/array to the variable, but the properties/elements of the existing object/array can still be modified.
On the other hand, an immutable object is an object whose state (properties and values) cannot be modified after it is created. This is achieved by using methods like `Object.freeze()` which makes the object immutable by preventing any changes to its properties.
```js
// Using const
const person = { name: 'John' };
person = { name: 'Jane' }; // Error: Assignment to constant variable
person.name = 'Jane'; // Allowed, person.name is now 'Jane'
// Using Object.freeze() to create an immutable object
const frozenPerson = Object.freeze({ name: 'John' });
frozenPerson.name = 'Jane'; // Fails silently (no error, but no change)
frozenPerson = { name: 'Jane' }; // Error: Assignment to constant variable
```
In the first example with `const`, reassigning a new object to `person` is not allowed, but modifying the `name` property is permitted. In the second example, `Object.freeze()` makes the `frozenPerson` object immutable, preventing any changes to its properties.
It's important to note that `Object.freeze()` creates a shallow immutable object. If the object contains nested objects or arrays, those nested data structures are still mutable unless frozen separately.
Therefore, while `const` provides immutability for primitive values, creating truly immutable objects requires using `Object.freeze()` or other immutability techniques like deep freezing or using immutable data structures from libraries like [Immer](https://immerjs.github.io/immer/) or [Immutable.js](https://immutable-js.com/).
## Various ways to implement immutability in plain JavaScript objects
Here are a few ways to add/simulate different forms of immutability in plain JavaScript objects.
### Immutable object properties
By combining `writable: false` and `configurable: false`, you can essentially create a constant (cannot be changed, redefined or deleted) as an object property, like:
```js
let myObject = {};
const myObject = {};
Object.defineProperty(myObject, 'number', {
value: 42,
writable: false,
@ -114,7 +139,7 @@ myObject.number = 43;
console.log(myObject.number); // 42
```
#### Prevent Extensions
### Preventing extensions on objects
If you want to prevent an object from having new properties added to it, but otherwise leave the rest of the object's properties alone, call `Object.preventExtensions(...)`:
@ -131,13 +156,39 @@ myObject.b; // undefined
In non-strict mode, the creation of `b` fails silently. In strict mode, it throws a `TypeError`.
#### Seal
### Sealing an object
`Object.seal()` creates a "sealed" object, which means it takes an existing object and essentially calls `Object.preventExtensions()` on it, but also marks all its existing properties as `configurable: false`.
`Object.seal()` creates a "sealed" object, which means it takes an existing object and essentially calls `Object.preventExtensions()` on it, but also marks all its existing properties as `configurable: false`. Therefore, not only can you not add any more properties, but you also cannot reconfigure or delete any existing properties, though you can still modify their values.
So, not only can you not add any more properties, but you also cannot reconfigure or delete any existing properties (though you can still modify their values).
```js
// Create an object
const person = {
name: 'John Doe',
age: 30,
};
#### Freeze
// Seal the object
Object.seal(person);
// Try to add a new property (this will fail silently)
person.city = 'New York'; // This has no effect
// Try to delete an existing property (this will fail silently)
delete person.age; // This has no effect
// Modify an existing property (this will work)
person.age = 35;
console.log(person); // Output: { name: 'John Doe', age: 35 }
// Try to re-configure an existing property descriptor (this will fail)
Object.defineProperty(person, 'name', { writable: false }); // TypeError: Cannot redefine property: name
// Check if the object is sealed
console.log(Object.isSealed(person)); // Output: true
```
### Freezing an object
`Object.freeze()` creates a frozen object, which means it takes an existing object and essentially calls `Object.seal()` on it, but it also marks all "data accessor" properties as writable:false, so that their values cannot be changed.
@ -147,12 +198,12 @@ This approach is the highest level of immutability that you can attain for an ob
let immutableObject = Object.freeze({});
```
Freezing an object does not allow new properties to be added to an object and prevents users from removing or altering the existing properties. `Object.freeze()` preserves the enumerability, configurability, writability and the prototype of the object. It returns the passed object and does not create a frozen copy.
Freezing an object does not allow new properties to be added to an object and prevents users from removing or altering the existing properties. `Object.freeze()` preserves the enumerability, configurability, writability and the `prototype` of the object. It returns the passed object and does not create a frozen copy.
`Object.freeze()` makes the object immutable. However, it is not necessarily constant. `Object.freeze` prevents modifications to the object itself and its direct properties, nested objects within the frozen object can still be modified.
```js
const obj = {
let obj = {
user: {},
};
@ -162,26 +213,26 @@ obj.user.name = 'John';
console.log(obj.user.name); //Output: 'John'
```
### What are the pros and cons of immutability?
## What are the pros and cons of immutability?
#### Pros
### Pros
- Easier change detection: Object equality can be determined in a performant and easy manner through referential equality. This is useful for comparing object differences in React and Redux.
- Less complicated: Programs with immutable objects are less complicated to think about, since you don't need to worry about how an object may evolve over time.
- **Easier change detection**: Object equality can be determined in a performant and easy manner through referential equality. This is useful for comparing object differences in React and Redux.
- **Less complicated**: Programs with immutable objects are less complicated to think about, since you don't need to worry about how an object may evolve over time.
- Easy sharing via references: One copy of an object is just as good as another, so you can cache objects or reuse the same object multiple times.
- Thread-safe: Immutable objects can be safely used between threads in a multi-threaded environment since there is no risk of them being modified in other concurrently running threads.
- Less memory needed: Using libraries like [Immer](https://immerjs.github.io/immer/) and [Immutable.js](https://immutable-js.com/), objects are modified using structural sharing and less memory is needed for having multiple objects with similar structures.
- No need for defensive copying: Defensive copies are no longer necessary when immutable objects are returning from or passed to functions, since there is no possibility an immutable object will be modified by it.
- **Thread-safe**: Immutable objects can be safely used between threads in a multi-threaded environment since there is no risk of them being modified in other concurrently running threads. In the most cases, JavaScript runs in a single-threaded environment
- **Less memory needed**: Using libraries like [Immer](https://immerjs.github.io/immer/) and [Immutable.js](https://immutable-js.com/), objects are modified using structural sharing and less memory is needed for having multiple objects with similar structures.
- **No need for defensive copying**: Defensive copies are no longer necessary when immutable objects are returning from or passed to functions, since there is no possibility an immutable object will be modified by it.
#### Cons
### Cons
- Complex to create yourself: Naive implementations of immutable data structures and its operations can result in extremely poor performance because new objects are created each time. It is recommended to use libraries for efficient immutable data structures and operations that leverage on structural sharing.
- Potential negative performance: Allocation (and deallocation) of many small objects rather than modifying existing ones can cause a performance impact. The complexity of either the allocator or the garbage collector usually depends on the number of objects on the heap.
- Complexity for cyclic data structures: Cyclic data structures such as graphs are difficult to build. If you have two objects which can't be modified after initialization, how can you get them to point to each other?
- **Complex to create yourself**: Naive implementations of immutable data structures and its operations can result in extremely poor performance because new objects are created each time. It is recommended to use libraries for efficient immutable data structures and operations that leverage on structural sharing.
- **Potential negative performance**: Allocation (and deallocation) of many small objects rather than modifying existing ones can cause a performance impact. The complexity of either the allocator or the garbage collector usually depends on the number of objects on the heap.
- **Complexity for cyclic data structures**: Cyclic data structures such as graphs are difficult to implement.
## Further reading
- [Object.defineProperty() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
- [Object.freeze() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
- [Object.seal() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
- [Object.preventExtensions() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
- [Object.preventExtensions() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)

View File

@ -1,14 +1,12 @@
---
title: Explain the differences between commonjs modules-and-es-modules ?
title: Explain the differences between CommonJS modules and ES modules
---
## TL;DR
In JavaScript, `modules` are reusable pieces of code that encapsulate functionality, making it easier to manage, maintain, and structure your applications. Modules allow you to break down your code into smaller, manageable parts, each with its own scope.
In JavaScript, modules are reusable pieces of code that encapsulate functionality, making it easier to manage, maintain, and structure your applications. Modules allow you to break down your code into smaller, manageable parts, each with its own scope.
**CommonJS**:
CommonJS is an older module system that was initially designed for server-side JavaScript development with Node.js. It uses the require function to load modules and the module.exports or exports object to define the exports of a module.
**CommonJS** is an older module system that was initially designed for server-side JavaScript development with Node.js. It uses the `require()` function to load modules and the `module.exports` or `exports` object to define the exports of a module.
```js
// my-module.js
@ -20,9 +18,7 @@ const myModule = require('./my-module.js');
console.log(myModule.value); // 42
```
**ES Modules**:
ES Modules (ECMAScript Modules) are the standardized module system introduced in ES6 (ECMAScript 2015). They use the import and export statements to handle module dependencies.
**ES Modules** (ECMAScript Modules) are the standardized module system introduced in ES6 (ECMAScript 2015). They use the `import` and `export` statements to handle module dependencies.
```js
// my-module.js
@ -33,16 +29,16 @@ import { value } from './my-module.js';
console.log(value); // 42
```
**CommonJs vs ES Modules**
**CommonJS vs ES modules**
| Feature | CommonJS | ES Modules |
| Feature | CommonJS | ES modules |
| --- | --- | --- |
| Module Syntax | `require()` for importing `module.exports` for exporting | `import` for importing `export` for exporting |
| Environment | Primarily used in `Node.js` for server-side development | Designed for both browser and server-side JavaScript (Node.js) |
| Environment | Primarily used in Node.js for server-side development | Designed for both browser and server-side JavaScript (Node.js) |
| Loading | Synchronous loading of modules | Asynchronous loading of modules |
| Structure | Dynamic imports, can be conditionally called | Static imports/exports at the top level |
| File Extensions | `.js` (default) | `.mjs` or `.js` (with `type`: `module` in `package.json`) |
| Browser Support | Not natively supported in browsers | Natively supported in modern browsers |
| File extensions | `.js` (default) | `.mjs` or `.js` (with `type: "module"` in `package.json`) |
| Browser support | Not natively supported in browsers | Natively supported in modern browsers |
| Optimization | Limited optimization due to dynamic nature | Allows for optimizations like tree-shaking due to static structure |
| Compatibility | Widely used in existing Node.js codebases and libraries | Newer standard, but gaining adoption in modern projects |
@ -50,15 +46,16 @@ console.log(value); // 42
## Modules in Javascript
`Modules` in JavaScript are a way to organize and encapsulate code into reusable and maintainable units. They allow developers to break down their codebase into smaller, self-contained pieces, promoting code reuse, separation of concerns, and better organization. There are two main module systems in JavaScript: `CommonJS` and `ES Modules`.
Modules in JavaScript are a way to organize and encapsulate code into reusable and maintainable units. They allow developers to break down their codebase into smaller, self-contained pieces, promoting code reuse, separation of concerns, and better organization. There are two main module systems in JavaScript: CommonJS and ES modules.
### CommonJS
CommonJS is an older module system that was initially designed for server-side JavaScript development with Node.js. It uses the require function to load modules and the module.exports or exports object to define the exports of a module.
CommonJS is an older module system that was initially designed for server-side JavaScript development with Node.js. It uses the require function to load modules and the `module.exports` or `exports` object to define the exports of a module.
- **Syntax**: Modules are included using `require()` and exported using `module.exports`.
- **Environment**: Primarily used in `Node.js`.
- **Execution**: Modules are loaded `synchronously`.
- **Execution**: Modules are loaded synchronously.
- Modules are loaded dynamically at runtime.
```js
// my-module.js
@ -70,21 +67,16 @@ const myModule = require('./my-module.js');
console.log(myModule.value); // 42
```
#### Key points about CommonJS:
- `Synchronous` loading of modules
- `Designed for server-side` environments (`Node.js`)
- Uses `require` for importing and `module.exports` for exporting
- Modules are `loaded dynamically at runtime`
### ES Modules
ES Modules (ECMAScript Modules) are the standardized module system introduced in ES6 (ECMAScript 2015). They use the import and export statements to handle module dependencies.
ES Modules (ECMAScript Modules) are the standardized module system introduced in ES6 (ECMAScript 2015). They use the `import` and `export` statements to handle module dependencies.
- **Syntax**: Modules are imported using `import` and exported using `export`.
- **Environment**: Can be used in both `browser` environments and `Node.js` (with certain configurations).
- **Execution**: Modules are loaded `asynchronously`.
- **Support**: Introduced in `ES6 (2015)`, now widely supported in modern browsers and `Node.js`.
- **Environment**: Can be used in both browser environments and Node.js (with certain configurations).
- **Execution**: Modules are loaded asynchronously.
- **Support**: Introduced in ES2015, now widely supported in modern browsers and Node.js.
- Modules are loaded statically at compile-time.
- Enables better performance due to static analysis and tree-shaking.
```js
// my-module.js
@ -95,17 +87,9 @@ import { value } from './my-module.js';
console.log(value); // 42
```
#### Key points about `ES Modules`:
- `Asynchronous loading` of modules
- Designed for both `client-side` (browsers) and `server-side` (`Node.js`)
- Uses `import` for importing and `export` for exporting
- Modules are loaded statically at `compile-time`
- Better performance due to `static analysis` and `tree-shaking`
## Summary
While `CommonJS` was the default module system in `Node.js` initially,`ES Modules` are now the recommended approach for new projects, as they provide better tooling, performance, and ecosystem compatibility. However, `CommonJS` modules are still widely used in existing code bases and libraries.
While CommonJS was the default module system in Node.js initially, ES modules are now the recommended approach for new projects, as they provide better tooling, performance, and ecosystem compatibility. However, CommonJS modules are still widely used in existing code bases and libraries especially for legacy dependencies.
## Further reading

View File

@ -4,23 +4,44 @@ title: Explain the differences on the usage of `foo` between `function foo() {}`
## TL;DR
The former is a function declaration while the latter is a function expression.
`function foo() {}` a function declaration while the `var foo = function() {}` is a function expression. The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behavior as `var`-declared variables).
### Function Declaration
If you try to invoke a function expression before it is declared, you will get an `Uncaught TypeError: XXX is not a function` error.
- When you want to create a function on the global scope and make it available throughout your code
- If a function is reusable and needs to be called multiple times
Function declarations can be called in the enclosing scope even before they are declared.
### Function Expression
```js
foo(); // 'FOOOOO'
function foo() {
console.log('FOOOOO');
}
```
- If a function is only needed once or in a specific context
- Use to limit the function availability and keep your global scope clean
Function expressions if called before they are declared will result in an error.
```js
foo(); // Uncaught TypeError: foo is not a function
var foo = function () {
console.log('FOOOOO');
};
```
Another key difference is in the scope of the function name. Function expressions can be named by defining it after the `function` and before the parenthesis. However when using named function expressions, the function name is only accessible within the function itself. Trying to access it outside will result in an error or `undefined`.
```js
const myFunc = function namedFunc() {
console.log(namedFunc); // Works
};
console.log(namedFunc); // undefined
```
**Note**: The examples uses `var` due to legacy reasons. Function expressions can be defined using `let` and `const` and the key difference is in the hoisting behavior of those keywords.
---
## Function Declaration
## Function declarations
A function declaration is a statement that defines a function with a name. It is typically used to declare a function that can be called multiple times throughout the code.
A function declaration is a statement that defines a function with a name. It is typically used to declare a function that can be called multiple times throughout the enclosing scope.
```js
function foo() {
@ -28,7 +49,7 @@ function foo() {
}
```
## Function Expression
## Function expressions
A function expression is an expression that defines a function and assigns it to a variable. It is often used when a function is needed only once or in a specific context.
@ -38,9 +59,15 @@ var foo = function () {
};
```
The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behavior as variables). For more explanation on hoisting, refer to the question on [hoisting](/questions/quiz/explain-hoisting). If you try to invoke a function expression before it is defined, you will get an `Uncaught TypeError: XXX is not a function` error.
**Note**: The examples uses `var` due to legacy reasons. Function expressions can be defined using `let` and `const` and the key difference is in the hoisting behavior of those keywords.
Function Declaration:
## Key differences
### Hoisting
The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behavior as `var`-declared variables). For more explanation on hoisting, refer to the quiz question on [hoisting](/questions/quiz/explain-hoisting). If you try to invoke a function expression before it is defined, you will get an `Uncaught TypeError: XXX is not a function` error.
Function declarations:
```js
foo(); // 'FOOOOO'
@ -49,7 +76,7 @@ function foo() {
}
```
Function Expression:
Function expressions:
```js
foo(); // Uncaught TypeError: foo is not a function
@ -58,57 +85,29 @@ var foo = function () {
};
```
## Use Cases
### Name scope
### Function Declaration
- **Global Functions**: When you need functions accessible from anywhere in your code, use function declarations at the top level of your script.
- **Readability and Maintainability**: Function declarations can improve readability by providing function names that act as documentation for what the function does.
### Function Expression
- **Callback**: Functions often passed as arguments to other functions (e.g., `array.forEach(callbackFunction)`) are typically defined as function expressions.
Function expressions can be named by defining it after the `function` and before the parenthesis. However when using named function expressions, the function name is only accessible within the function itself. Trying to access it outside will result in `undefined` and calling it will result in an error.
```js
const numbers = [1, 2, 3, 4, 5];
// `forEach` method expects a callback function
numbers.forEach(function (element) {
console.log(element * 2);
});
```
- **Immediately Invoked Function Expression (IIFE)**: Function expressions can be wrapped in parentheses and followed by parentheses () to create IIFEs that execute immediately after definition, often used for private variable scoping or module creation.
```js
(function () {
// Private variables and functions within the IIFE
let counter = 0;
function incrementCounter() {
counter++;
console.log('Counter:', counter);
}
incrementCounter();
})();
const myFunc = function namedFunc() {
console.log(namedFunc); // Works
};
console.log(namedFunc); // undefined
```
## When to use each
### Function Declaration
- When you want to create a function on the global scope and make it available throughout your code
- If a function is reusable and needs to be called multiple times
### Function Expression
- If a function is only needed once or in a specific context
- Use to limit the function availability and keep your global scope clean
- Function declarations:
- When you want to create a function on the global scope and make it available throughout the enclosing scope.
- If a function is reusable and needs to be called multiple times.
- Function expressions:
- If a function is only needed once or in a specific context.
- Use to limit the function availability to subsequent code and keep the enclosing scope clean.
In general, it's preferable to use function declarations to avoid the mental overhead of determining if a function can be called. The practical usages of function expressions is quite rare.
## Further reading
- [Function declaration | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)
- [Function expression | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)
- [Function expression | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)

View File

@ -1,31 +1,33 @@
---
title: How does garbage collection in the context of javascript work ?
title: How does JavaScript garbage collection work?
---
## TL;DR
Garbage collection in JavaScript is an automatic memory management mechanism that reclaims memory occupied by objects and variables that are no longer in use by the program. Here's how it works:
Garbage collection in JavaScript is an automatic memory management mechanism that reclaims memory occupied by objects and variables that are no longer in use by the program. The two most common algorithms are mark-and-sweep and generational garbage collection.
**Mark and Sweep Algorithm**:
**Mark-and-sweep**
The most common garbage collection algorithm used in JavaScript is the Mark and Sweep algorithm. It operates in two phases:
The most common garbage collection algorithm used in JavaScript is the Mark-and-sweep algorithm. It operates in two phases:
- **Marking Phase**: The garbage collector traverses the object graph, starting from the root objects (global variables, currently executing functions, etc.), and marks all reachable objects as "in-use".
- **Sweeping Phase**: The garbage collector sweeps through memory, removing all unmarked objects, as they are considered unreachable and no longer needed.
- **Marking phase**: The garbage collector traverses the object graph, starting from the root objects (global variables, currently executing functions, etc.), and marks all reachable objects as "in-use".
- **Sweeping phase**: The garbage collector sweeps through memory, removing all unmarked objects, as they are considered unreachable and no longer needed.
This algorithm effectively identifies and removes objects that have become unreachable, freeing up memory for new allocations.
**Generational Garbage Collection**:
**Generational garbage collection**
Modern JavaScript engines also employ a technique called **Generational Garbage Collection** to optimize the process. Objects are divided into different generations based on their age and usage patterns. Frequently accessed objects are moved to younger generations, while less frequently used objects are promoted to older generations. This optimization reduces the overhead of garbage collection by focusing on the younger generations, where most objects are short-lived.
Leveraged by modern JavaScript engines, objects are divided into different generations based on their age and usage patterns. Frequently accessed objects are moved to younger generations, while less frequently used objects are promoted to older generations. This optimization reduces the overhead of garbage collection by focusing on the younger generations, where most objects are short-lived.
Different JavaScript engines (differs according to browsers) implement different garbage collection algorithms and there's no standard way of doing garbage collection.
---
## Garbage collection in JavaScript
Garbage collection in JavaScript is an automatic process managed by the JavaScript engine, designed to reclaim memory occupied by objects that are no longer needed. This helps prevent memory leaks and optimizes the use of available memory. Heres an overview of how garbage collection works in JavaScript:
Garbage collection in JavaScript is an automatic process managed by the JavaScript engine, designed to reclaim memory occupied by objects that are no longer needed. This helps prevent memory leaks and optimizes the use of available memory. Here's an overview of how garbage collection works in JavaScript:
### Memory Management Basics
### Memory management basics
JavaScript allocates memory for objects, arrays, and other variables as they are created. Over time, some of these objects become unreachable because there are no references to them. Garbage collection is the process of identifying these unreachable objects and reclaiming their memory.
@ -36,30 +38,25 @@ The primary concept in JavaScript garbage collection is reachability. An object
- **Global variables**: Objects referenced by global variables are always reachable.
- **Local variables and function parameters**: These objects are reachable as long as the function is executing.
- **Closure variables**: Objects referenced by closures are reachable if the closure is reachable.
- **DOM and other system roots**: Objects referenced by the `DOM` or other host objects.
- **DOM and other system roots**: Objects referenced by the DOM or other host objects.
If there is a chain of references from a root to an object, that object is considered reachable.
### Garbage Collection Algorithms
1. **Mark-and-Sweep Algorithm**:
### Garbage collection algorithms
1. **Mark-and-sweep**:
- **Mark Phase**: The garbage collector starts from the root objects and marks all reachable objects.
- **Sweep Phase**: It then scans memory for objects that were not marked and reclaims their memory.
2. **Reference Counting**:
2. **Reference counting**:
- This algorithm keeps a count of references to each object. When an object's reference count drops to zero, it is considered unreachable and can be collected.
- A drawback of reference counting is that it cannot handle circular references well (e.g., two objects referencing each other but not referenced by any other object).
3. **Generational Garbage Collection**:
3. **Generational garbage collection**:
- Memory is divided into generations: young and old.
- Objects are initially allocated in the young generation.
- Objects that survive multiple collections are promoted to the old generation.
- Young generation collections are more frequent and faster, while old generation collections are less frequent but cover more objects.
### JavaScript Engine Implementations
### JavaScript engine implementations
Different JavaScript engines use variations of these algorithms:
@ -67,17 +64,26 @@ Different JavaScript engines use variations of these algorithms:
- **SpiderMonkey (Mozilla Firefox)**: Uses incremental and generational garbage collection.
- **JavaScriptCore (Safari)**: Uses a mark-and-sweep algorithm with generational collection.
### Best Practices to Avoid Memory Leaks
### Memory leaks
Memory leaks in JavaScript occur when a program fails to release memory that it no longer needs, causing the program to consume more and more memory over time.
Memory leaks in JavaScript can occur due to various reasons, including:
- **Accidental global variables**: Unintentionally creating global variables that remain in memory even after they are no longer needed.
- **Closures**: Improper use of closures, where an inner function retains references to variables from an outer function's scope, preventing the outer function's scope from being garbage collected.
- **Event listeners**: Failing to remove event listeners or callbacks when they are no longer needed, causing the associated objects to remain in memory.
- **Caching**: Implementing caches without proper eviction logic, leading to unbounded memory growth over time.
- **Detached DOM node references**: Keeping references to detached DOM nodes, preventing them from being garbage collected.
- **Forgotten timers or callbacks**: Failing to clear timers or callbacks when they are no longer needed, causing their associated data to remain in memory.
To avoid leaking memory:
- **Remove event listeners**: Always remove event listeners when they are no longer needed.
- **Clear references in closures**: Avoid holding unnecessary references in closures.
- **Manage DOM references**: Explicitly remove DOM nodes and their references when they are no longer needed.
- **Avoid global variables**: Minimize the use of global variables to reduce the risk of inadvertently keeping references alive.
## Summary
Understanding garbage collection helps developers write more efficient and memory-conscious code, ensuring that applications run smoothly and with minimal memory footprint.
## Further reading
- [Garbage collection - MDN](https://developer.mozilla.org/en-US/docs/Glossary/Garbage_collection)

View File

@ -1,5 +1,5 @@
{
"slug": "how-does-garbage-collection-in-the-context-of-javascript-work",
"slug": "how-does-javascript-garbage-collection-work",
"languages": [],
"companies": [],
"premium": false,

View File

@ -4,16 +4,18 @@ title: What advantage is there for using the arrow syntax for a method in a cons
## TL;DR
The main advantage of using an arrow function as a method inside a constructor is that the value of `this` gets set at the time of the function creation and can't change after that. So, when the constructor is used to create a new object, `this` will always refer to that object. For example, let's say we have a `Person` constructor that takes a first name as an argument has two methods to `console.log` that name, one as a regular function and one as an arrow function:
The main advantage of using an arrow function as a method inside a constructor is that the value of `this` gets set at the time of the function creation and can't change after that. When the constructor is used to create a new object, `this` will always refer to that object.
For example, let's say we have a `Person` constructor that takes a first name as an argument has two methods to `console.log()` that name, one as a regular function and one as an arrow function:
```js
const Person = function (firstName) {
this.firstName = firstName;
const Person = function (name) {
this.name = name;
this.sayName1 = function () {
console.log(this.firstName);
console.log(this.name);
};
this.sayName2 = () => {
console.log(this.firstName);
console.log(this.name);
};
};
@ -23,37 +25,37 @@ const dave = new Person('Dave');
john.sayName1(); // John
john.sayName2(); // John
// The regular function can have its 'this' value changed, but the arrow function cannot
john.sayName1.call(dave); // Dave (because "this" is now the dave object)
// The regular function can have its `this` value changed, but the arrow function cannot
john.sayName1.call(dave); // Dave (because `this` is now the dave object)
john.sayName2.call(dave); // John
john.sayName1.apply(dave); // Dave (because 'this' is now the dave object)
john.sayName1.apply(dave); // Dave (because `this` is now the dave object)
john.sayName2.apply(dave); // John
john.sayName1.bind(dave)(); // Dave (because 'this' is now the dave object)
john.sayName1.bind(dave)(); // Dave (because `this` is now the dave object)
john.sayName2.bind(dave)(); // John
var sayNameFromWindow1 = john.sayName1;
sayNameFromWindow1(); // undefined (because 'this' is now the window object)
const sayNameFromWindow1 = john.sayName1;
sayNameFromWindow1(); // undefined (because `this` is now the window object)
var sayNameFromWindow2 = john.sayName2;
const sayNameFromWindow2 = john.sayName2;
sayNameFromWindow2(); // John
```
The main takeaway here is that `this` can be changed for a normal function, but the context always stays the same for an arrow function. So even if you are passing around your arrow function to different parts of your application, you wouldn't have to worry about the context changing.
The main takeaway here is that `this` can be changed for a normal function, but `this` always stays the same for an arrow function. So even if you are passing around your arrow function to different parts of your application, you wouldn't have to worry about the value of `this` changing.
---
## Arrow functions
Arrow functions are introduced in ES6 and it provides a concise way to write functions in Javascript. One of the key features of arrow function is that it lexically bind the `this` value, which means that it takes the `this` value from containing scope.
Arrow functions are introduced in ES2015 and it provides a concise way to write functions in Javascript. One of the key features of arrow function is that it lexically bind the `this` value, which means that it takes the `this` value from enclosing scope.
### Syntax
Arrow functions use the `=>` syntax instead of the function keyword. The basic syntax is:
```js
let myFunction = (arg1, arg2, ...argN) => {
const myFunction = (arg1, arg2, ...argN) => {
// function body
};
```
@ -61,38 +63,46 @@ let myFunction = (arg1, arg2, ...argN) => {
If the function body has only one expression, you can omit the curly braces and the return keyword:
```js
let myFunction = (arg1, arg2, ...argN) => expression;
const myFunction = (arg1, arg2, ...argN) => expression;
```
### Examples
```js
// Arrow function with parameters
let multiply = (x, y) => x * y;
const multiply = (x, y) => x * y;
// Arrow function with no parameters
let sayHello = () => 'Hello, World!';
// Arrow function with a single parameter (parentheses can be omitted)
let square = (x) => x * x;
const sayHello = () => 'Hello, World!';
```
### Advantages
- Arrow functions provide a more concise syntax, especially for short functions.
- They have an implicit return for single-line functions.
- Arrow functions lexically bind the `this` value, inheriting it from the enclosing scope.
- **Concise**: Arrow functions provide a more concise syntax, especially for short functions.
- **Implicit return**: They have an implicit return for single-line functions.
- **Value of `this` is predictable**: Arrow functions lexically bind the `this` value, inheriting it from the enclosing scope.
### Limitations
- Arrow functions cannot be used as constructors and will throw an error when used with the `new` keyword.
Arrow functions cannot be used as constructors and will throw an error when used with the `new` keyword.
```js
const Foo = () => {};
const foo = new Foo(); // TypeError: Foo is not a constructor
```
- They do not have their own `this`,` arguments`, `super`. Since arrow functions do not have their own this, they are not suitable for defining methods in an object. Traditional function expressions or function declarations should be used instead.
They also do not have `arguments` keyword; the arguments have to be obtained from using the rest operator (`...`) in the arguments.
```js
const arrowFunction = (...args) => {
console.log(arguments); // Throws a TypeError
console.log(args); // [1, 2, 3]
};
arrowFunction(1, 2, 3);
```
Since arrow functions do not have their own `this`, they are not suitable for defining methods in an object. Traditional function expressions or function declarations should be used instead.
```js
const obj = {
@ -103,20 +113,20 @@ const obj = {
console.log(obj.getValue()); // undefined
```
## What makes arrow function good to be used for a method in constructor
## Why arrow functions are useful
One of the most notable features of arrow functions is their behavior with `this`. Unlike regular functions, arrow functions do not have their own `this`. Instead, they inherit `this` from the parent scope at the time they are defined. This makes arrow functions particularly useful for scenarios like event handlers, callbacks, and methods in classes.
### Arrow Function inside function constructor
### Arrow functions inside function constructors
```js
const Person = function (firstName) {
this.firstName = firstName;
const Person = function (name) {
this.name = name;
this.sayName1 = function () {
console.log(this.firstName);
console.log(this.name);
};
this.sayName2 = () => {
console.log(this.firstName);
console.log(this.name);
};
};
@ -126,24 +136,24 @@ const dave = new Person('Dave');
john.sayName1(); // John
john.sayName2(); // John
// The regular function can have its 'this' value changed, but the arrow function cannot
john.sayName1.call(dave); // Dave (because "this" is now the dave object)
// The regular function can have its `this` value changed, but the arrow function cannot
john.sayName1.call(dave); // Dave (because `this` is now the dave object)
john.sayName2.call(dave); // John
john.sayName1.apply(dave); // Dave (because 'this' is now the dave object)
john.sayName1.apply(dave); // Dave (because `this` is now the dave object)
john.sayName2.apply(dave); // John
john.sayName1.bind(dave)(); // Dave (because 'this' is now the dave object)
john.sayName1.bind(dave)(); // Dave (because `this` is now the dave object)
john.sayName2.bind(dave)(); // John
var sayNameFromWindow1 = john.sayName1;
sayNameFromWindow1(); // undefined (because 'this' is now the window object)
const sayNameFromWindow1 = john.sayName1;
sayNameFromWindow1(); // undefined (because `this` is now the window object)
var sayNameFromWindow2 = john.sayName2;
const sayNameFromWindow2 = john.sayName2;
sayNameFromWindow2(); // John
```
### Arrow Function in an Event Handler
### Arrow functions in event handlers
```js
const button = document.getElementById('myButton');
@ -159,9 +169,9 @@ button.addEventListener('click', () => {
});
```
This can be particularly helpful in React class components. If you define a class method for something such as a click handler using a normal function, and then you pass that click handler down into a child component as a prop, you will need to also bind `this` in the constructor of the parent component. If you instead use an arrow function, there is no need to also bind "this", as the method will automatically get its "this" value from its enclosing lexical context. (See this article for an excellent demonstration and sample code: https://medium.com/@machnicki/handle-events-in-react-with-arrow-functions-ede88184bbb)
This can be particularly helpful in React class components. If you define a class method for something such as a click handler using a normal function, and then you pass that click handler down into a child component as a prop, you will need to also bind `this` in the constructor of the parent component. If you instead use an arrow function, there is no need to bind `this`, as the method will automatically get its `this` value from its enclosing lexical context. See this [article](https://medium.com/@machnicki/handle-events-in-react-with-arrow-functions-ede88184bbb) for an excellent demonstration and sample code.
## Resources
## Further reading
- [Arrow function expressions - MDN ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
- [How to Use JavaScript Arrow Functions Explained in Detail](https://www.freecodecamp.org/news/javascript-arrow-functions-in-depth/)
- [How to Use JavaScript Arrow Functions Explained in Detail](https://www.freecodecamp.org/news/javascript-arrow-functions-in-dep)

View File

@ -1,16 +1,12 @@
---
title: What are iterators and generators and what are they used for ?
title: What are iterators and generators and what are they used for?
---
## TL;DR
In JavaScript, `iterators` and `generators` are powerful tools for managing sequences of data and controlling the flow of execution in a more flexible way.
In JavaScript, iterators and generators are powerful tools for managing sequences of data and controlling the flow of execution in a more flexible way.
**Iterators**
An iterator is an object that defines a sequence and potentially a return value upon its termination. It adheres to a specific interface.
**Iterator interface**:
**Iterators** are objects that define a sequence and potentially a return value upon its termination. It adheres to a specific interface:
- An iterator object must implement a `next()` method.
- The `next()` method returns an object with two properties:
@ -37,14 +33,7 @@ while (!result.done) {
}
```
**Generators**
`Generators` are a special type of function that **can pause execution and resume at a later point**. They are used to create `iterators` in a more convenient and readable way
**Generator function**
- Defined using the `function*` syntax.
- Use the `yield` keyword to yield values.
**Generators** are a special functions that **can pause execution and resume at a later point**. It uses the `function*` syntax and the `yield` keyword to control the flow of execution. When you call a generator function, it doesn't execute completely like a regular function. Instead, it returns an iterator object. Calling the `next()` method on the returned iterator advances the generator to the next `yield` statement, and the value after `yield` becomes the return value of `next()`.
```js
function* numberGenerator() {
@ -64,20 +53,22 @@ console.log(gen.next()); // { value: 5, done: false }
console.log(gen.next()); // { value: undefined, done: true }
```
Generators are powerful for creating iterators on-demand, especially for infinite sequences or complex iteration logic. They can be used for:
- Lazy evaluation processing elements only when needed, improving memory efficiency for large datasets.
- Implementing iterators for custom data structures.
- Creating asynchronous iterators for handling data streams.
---
## `Iterator` and `generator` in JavaScript
`Iterators` and `generators` are powerful features in JavaScript that provide a standardized way to iterate over data structures and create custom iterables.
### `Iterators`
## Iterators
Iterators are objects that define a sequence and provide a `next()` method to access the next value in the sequence. They are used to iterate over data structures like `arrays`, `strings`, and custom `objects`. The key use case of iterators include:
- Implementing the iterator protocol to make custom objects iterable, allowing them to be used with `for...of` loops and other language constructs that expect iterables
- Implementing the iterator protocol to make custom objects iterable, allowing them to be used with `for...of` loops and other language constructs that expect iterables.
- Providing a standard way to iterate over different data structures, making code more reusable and maintainable.
#### Creating a custom iterator for a range of numbers:
### Creating a custom iterator for a range of numbers
In JavaScript, we can provide a default implementation for iterator by implementing `[Symbol.iterator]()` in any custom object.
@ -105,10 +96,10 @@ class Range {
if (current <= end) {
// ...return an object with the current value and done set to false
return { value: current++, done: false };
} else {
// ...otherwise, return an object with value set to undefined and done set to true
return { value: undefined, done: true };
}
// ...otherwise, return an object with value set to undefined and done set to true
return { value: undefined, done: true };
},
};
}
@ -123,78 +114,78 @@ for (const number of range) {
}
```
### In-built objects with iterator protocol
### Built-in objects using the iterator protocol
In JavaScript, several built-in objects implement the iterator protocol, meaning they have a default `@@iterator` method. This allows them to be used in constructs like `for...of` loops and with the spread operator. Here are some of the key built-in objects that implement iterators:
1. **Arrays**: Arrays have a built-in iterator that allows you to iterate over their elements.
```js
const array = [1, 2, 3];
const iterator = array[Symbol.iterator]();
```js
const array = [1, 2, 3];
const iterator = array[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
for (const value of array) {
console.log(value); // Logs 1, 2, 3
}
```
for (const value of array) {
console.log(value); // Logs 1, 2, 3
}
```
2. **Strings**: Strings have a built-in iterator that allows you to iterate over their characters.
```js
const string = 'hello';
const iterator = string[Symbol.iterator]();
```js
const string = 'hello';
const iterator = string[Symbol.iterator]();
console.log(iterator.next()); // { value: "h", done: false }
console.log(iterator.next()); // { value: "e", done: false }
console.log(iterator.next()); // { value: "l", done: false }
console.log(iterator.next()); // { value: "l", done: false }
console.log(iterator.next()); // { value: "o", done: false }
console.log(iterator.next()); // { value: undefined, done: true }
console.log(iterator.next()); // { value: "h", done: false }
console.log(iterator.next()); // { value: "e", done: false }
console.log(iterator.next()); // { value: "l", done: false }
console.log(iterator.next()); // { value: "l", done: false }
console.log(iterator.next()); // { value: "o", done: false }
console.log(iterator.next()); // { value: undefined, done: true }
for (const char of string) {
console.log(char); // Logs h, e, l, l, o
}
```
for (const char of string) {
console.log(char); // Logs h, e, l, l, o
}
```
3. **DOM NodeLists**
```js
const nodeList = document.querySelectorAll('div');
const iterator = nodeList[Symbol.iterator]();
```js
const nodeList = document.querySelectorAll('div');
const iterator = nodeList[Symbol.iterator]();
console.log(iterator.next()); // { value: firstDiv, done: false }
console.log(iterator.next()); // { value: secondDiv, done: false }
// ...
console.log(iterator.next()); // { value: firstDiv, done: false }
console.log(iterator.next()); // { value: secondDiv, done: false }
// ...
for (const node of nodeList) {
console.log(node); // Logs each <div> element
}
```
for (const node of nodeList) {
console.log(node); // Logs each <div> element
}
```
Similarly `Map` and `Set` also have inbuilt `iterator`.
`Map`s and `Set`s also have built-in iterators.
### `Generators`:
## Generators
`Generators` are a special kind of function that can pause and resume their execution, allowing them to generate a sequence of values on-the-fly. They are commonly used to create iterators but have other applications as well. The key use cases of generators include:
Generators are a special kind of function that can pause and resume their execution, allowing them to generate a sequence of values on-the-fly. They are commonly used to create iterators but have other applications as well. The key use cases of generators include:
- Creating iterators in a more concise and readable way compared to manually implementing the iterator protocol.
- Implementing lazy evaluation, where values are generated only when needed, saving memory and computation time
- Simplifying asynchronous programming by allowing code to be written in a synchronous-looking style using yield and await
- Creating iterators is a more concise and readable way compared to manually implementing the iterator protocol.
- Implementing lazy evaluation, where values are generated only when needed, saving memory and computation time.
- Simplifying asynchronous programming by allowing code to be written in a synchronous-looking style using `yield` and `await`.
#### Generators provide several benefits:
Generators provide several benefits:
- **Lazy Evaluation**: They generate values on the fly and only when required, which is memory efficient.
- **Pause and Resume**: Generators can pause execution (via `yield`) and can also receive new data upon resuming.
- **Asynchronous Iteration**: With the advent of `async/await`, generators can be used to manage asynchronous data flows.
- **Lazy evaluation**: They generate values on the fly and only when required, which is memory efficient.
- **Pause and resume**: Generators can pause execution (via `yield`) and can also receive new data upon resuming.
- **Asynchronous iteration**: With the advent of `async/await`, generators can be used to manage asynchronous data flows.
#### Creating an iterator using a generator function:
### Creating an iterator using a generator function
We can rewrite our `Range` example to use generator function:
We can rewrite our `Range` example to use a generator function:
```js
// Define a class named Range
@ -228,7 +219,7 @@ for (const number of range) {
}
```
#### Iterating Over Data Streams
### Iterating over data streams
Generators are well-suited for iterating over data streams, such as fetching data from an API or reading files. This example demonstrates using a generator to fetch data from an API in batches:
@ -250,9 +241,9 @@ for await (const batch of dataGenerator) {
}
```
This generator function `fetchDataInBatches` fetches data from an API in batches of a specified size. It yields each batch of data, allowing you to process it before fetching the next batch. This approach can be more memory-efficient than fetching all data at once
This generator function `fetchDataInBatches` fetches data from an API in batches of a specified size. It yields each batch of data, allowing you to process it before fetching the next batch. This approach can be more memory-efficient than fetching all data at once.
#### Implementing Asynchronous Iterators
#### Implementing asynchronous iterators
Generators can be used to implement asynchronous iterators, which are useful for working with asynchronous data sources. This example demonstrates an asynchronous iterator for fetching data from an API:
@ -276,7 +267,7 @@ for await (const chunk of asyncIterator) {
The generator function `fetchDataAsyncIterator` is an asynchronous iterator that fetches data from an API in pages. It yields each page of data, allowing you to process it before fetching the next page. This approach can be useful for handling large datasets or long-running operations.
Generators are also used extensively in JavaScript libraries and frameworks, such as **Redux-Saga** and **RxJS**, for handling asynchronous operations and reactive programming
Generators are also used extensively in JavaScript libraries and frameworks, such as [Redux-Saga](https://redux-saga.js.org/) and [RxJS](https://rxjs.dev/), for handling asynchronous operations and reactive programming.
## Summary

View File

@ -0,0 +1,88 @@
---
title: What are JavaScript object getters and setters for?
---
## TL;DR
JavaScript object getters and setters are used to control access to an object's properties. They provide a way to encapsulate the implementation details of a property and define custom behavior when getting or setting its value.
Getters and setters are defined using the `get` and `set` keywords, respectively, followed by a function that is executed when the property is accessed or assigned a new value.
Here's a code example demonstrating the use of getters and setters:
```js
const person = {
_name: 'John Doe', // Private property
get name() {
// Getter
return this._name;
},
set name(newName) {
// Setter
if (newName.trim().length > 0) {
this._name = newName;
} else {
console.log('Invalid name');
}
},
};
// Accessing the name property using the getter
console.log(person.name); // Output: 'John Doe'
// Setting the name property using the setter
person.name = 'Jane Smith'; // Setter is called
console.log(person.name); // Output: 'Jane Smith'
person.name = ''; // Setter is called, but the value is not set due to validation
console.log(person.name); // Output: 'Jane Smith'
```
---
## JavaScript object getters and setters
In JavaScript, getters and setters are special methods that allow you to control how properties of an object are accessed and modified.
- **Getters**: Functions that are invoked whenever you try to access a property using dot notation (e.g., `obj.name`). They provide a way to customize the value that is returned when the property is read.
- **Setters**: Functions that are called when you try to assign a value to a property using dot notation with the assignment operator (e.g., `obj.name = "John"`). They allow you to perform actions like data validation, formatting, or side effects before the actual value is stored in the object.
```js
const person = {
_firstName: 'John',
_lastName: 'Doe',
get fullName() {
return `${this._firstName} ${this._lastName}`;
},
set fullName(value) {
const parts = value.split(' ');
this._firstName = parts[0];
this._lastName = parts[1];
},
};
console.log(person.fullName); // Output: John Doe
person.fullName = 'Jane Smith';
console.log(person.fullName); // Output: Jane Smith
```
In this example, the `fullName` property doesn't have a direct value stored in the object. The getter function calculates it by combining the `_firstName` and `_lastName` properties. The setter splits the assigned value into first and last names and updates the internal properties accordingly.
## Benefits
Getters and setters provide several benefits:
1. **Encapsulation**: They allow you to encapsulate the implementation details of a property, making it easier to change the internal representation without affecting external code that uses the property.
1. **Data validation**: Setters can be used to validate the values being assigned to a property, ensuring data integrity and consistency.
1. **Computed Properties**: Getters can be used to compute and return a derived value based on other properties or calculations.
1. **Side effects**: Setters can be used to perform side effects when a property is changed. For example, you might update a related property or trigger an action when a specific value is assigned/modified, such as logging or debugging.
## Further reading
- [Object.defineProperty() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
- [Property flags and descriptors | Javascript.info](https://javascript.info/property-descriptors)
- [Object.seal() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)

View File

@ -1,5 +1,5 @@
{
"slug": "what-are-property-flags-and-descriptors",
"slug": "what-are-javascript-object-getters-and-settes-for",
"languages": [],
"companies": [],
"premium": false,

View File

@ -0,0 +1,122 @@
---
title: What are JavaScript object property flags and descriptors?
---
## TL;DR
In JavaScript, property flags and descriptors manage the behavior and attributes of object properties.
**Property flags**
Property flags are used to specify the behavior of a property on an object. Here are the available flags:
- `writable`: Specifies whether the property can be written to. Defaults to `true`.
- `enumerable`: Specifies whether the property is enumerable. Defaults to `true`.
- `configurable`: Specifies whether the property can be deleted or its attributes changed. Default is `true`.
**Property descriptors**
These provide detailed information about an object's property, including its value and flags. They are retrieved using `Object.getOwnPropertyDescriptor()` and set using `Object.defineProperty()`.
The use cases of property descriptors are as follows:
- Making a property non-writable by setting `writable: false` to ensure data consistency.
- Hiding a property from enumeration by setting `enumerable: false`.
- Preventing property deletion and modification by setting `configurable: false`.
- Freezing or sealing objects to prevent modifications globally.
---
## JavaScript object property flags and descriptors
In JavaScript, property flags and descriptors are used to manage the behavior and attributes of object properties. These flags and descriptors are essential for understanding how properties are accessed, modified, and inherited.
## Property flags
Property flags are used to specify the behavior of a property. They are set using the `Object.defineProperty()` method, which allows you to define a property on an object with specific attributes. The available property flags are:
- `writable`: Specifies whether the property can be written to. Defaults to `true`.
- `enumerable`: Specifies whether the property is enumerable. Defaults to `true`.
- `configurable`: Specifies whether the property can be deleted or its attributes changed. Default is `true`.
## Property descriptors
Property descriptors provide detailed information about an object's property, encapsulating its value and flags. They are retrieved using `Object.getOwnPropertyDescriptor()` and set using `Object.defineProperty()`
```js
let user = { name: 'John Doe' };
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor); // {value: "John Doe", writable: true, enumerable: true, configurable: true}
```
## Manipulating property flags
### `writable` flag
The `writable` flag specifies whether a property can be written to. When `writable` is `false`, trying to assign value to the property fails silently in non-strict mode, and it throws a `TypeError` in strict mode.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
writable: false,
value: 'John Doe',
});
console.log(obj.name); // Output: John Doe
obj.name = 'Jane Doe'; // TypeError: Cannot assign to read only property 'name' of object '#<Object>'
```
### `enumerable` flag
The `enumerable` flag specifies whether a property is enumerable. The `enumerable flag` is set to `true`, which means the property is visible in a `for...in` loop.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
enumerable: false,
value: 'John Doe',
});
for (const prop in obj) {
console.log(prop); // Output: nothing
}
const obj1 = {};
Object.defineProperty(obj1, 'name', {
enumerable: true,
value: 'John Doe',
});
for (const prop in obj1) {
console.log(prop); // Output: name
}
```
## `configurable` flag
The `configurable` flag specifies whether a property can be deleted or its attributes changed. When `configurable` is `false`, trying to delete or change the property fails silently in non-strict mode, and it throws a `TypeError` in strict mode.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
configurable: false,
value: 'John Doe',
});
delete obj.name; // Output: TypeError: Cannot delete property 'name' of #<Object>
```
## `Object.seal()`
The `Object.seal()` method in JavaScript effectively prevents the addition or removal of properties from the object, while still allowing the modification of existing property values. It also makes all properties non-configurable, meaning their descriptors (like `writable`, `enumerable`, and `configurable`) cannot be changed.
## Further reading
- [Object.defineProperty() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
- [Property flags and descriptors | Javascript.info](https://javascript.info/property-descriptors)
- [Object.seal() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)

View File

@ -0,0 +1,11 @@
{
"slug": "what-are-javascript-object-property-flags-and-descriptors",
"languages": [],
"companies": [],
"premium": false,
"duration": 5,
"published": true,
"topics": ["javascript"],
"importance": "medium",
"difficulty": "medium"
}

View File

@ -0,0 +1,97 @@
---
title: What are JavaScript polyfills for?
---
## TL;DR
Polyfills in JavaScript are pieces of code that provide modern functionality to older browsers that lack native support for those features. They bridge the gap between the JavaScript language features and APIs available in modern browsers and the limited capabilities of older browser versions.
They can be implemented manually or included through libraries and are often used in conjunction with feature detection.
Common use cases include:
- **New JavaScript Methods**: For example, `Array.prototype.includes()`, `Object.assign()`, etc.
- **New APIs**: Such as `fetch`, `Promise`, `IntersectionObserver`, etc. Modern browsers support these now but for a long time they have to be polyfilled.
Libraries and services for polyfills:
- **`core-js`**: A modular standard library for JavaScript which includes polyfills for a wide range of ECMAScript features.
```js
import 'core-js/actual/array/flat-map'; // With this, Array.prototype.flatMap is available to be used.
[1, 2].flatMap((it) => [it, it]); // => [1, 1, 2, 2]
```
- **Polyfill.io**: A service that provides polyfills based on the features and user agents specified in the request.
```js
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
```
---
## Polyfills in JavaScript
Polyfills in JavaScript are pieces of code (usually JavaScript) that provide modern functionality on older browsers that do not natively support it. They enable developers to use newer features of the language and APIs while maintaining compatibility with older environments.
## How polyfills work
Polyfills detect if a feature or API is missing in a browser and provide a custom implementation of that feature using existing JavaScript capabilities. This allows developers to write code using the latest JavaScript features and APIs without worrying about browser compatibility issues.
For example, let's consider the `Array.prototype.includes()` method, which determines if an array includes a specific element. This method is not supported in older browsers like Internet Explorer 11. To address this, we can use a polyfill:
```js
// Polyfill for Array.prototype.includes()
if (!Array.prototype.includes) {
Array.prototype.includes = function (searchElement) {
for (var i = 0; i < this.length; i++) {
if (this[i] === searchElement) {
return true;
}
}
return false;
};
}
```
By including this polyfill, we can safely use `Array.prototype.includes()` even in browsers that don't support it natively.
## Implementing polyfills
1. **Identify the missing feature**: Determine if the feature is compatible with the target browsers or detect its presence using feature detection methods like `typeof`, `in`, or `window`.
1. **Write the fallback implementation**: Develop the fallback implementation that provides similar functionality, either using a pre-existing polyfill library or pure JavaScript code.
1. **Test the polyfill**: Thoroughly test the polyfill to ensure it functions as intended across different contexts and browsers.
1. **Implement the polyfill**: Enclose the code that uses the missing feature in an if statement that checks for feature support. If not supported, run the polyfill code instead.
### Considerations
- **Selective loading**: Polyfills should only be loaded for browsers that need them to optimize performance.
- **Feature detection**: Perform feature detection before applying a polyfill to avoid overwriting native implementations or applying unnecessary polyfills.
- **Size and performance**: Polyfills can increase the JavaScript bundle size, so minification and compression techniques should be used to mitigate this impact.
- **Existing libraries**: Consider using existing libraries and tools that offer comprehensive polyfill solutions for multiple features, handling feature detection, conditional loading, and fallbacks efficiently
### Libraries and services for polyfills
- **`core-js`**: A modular standard library for JavaScript which includes polyfills for a wide range of ECMAScript features.
```js
import 'core-js/actual/array/flat-map'; // With this, Array.prototype.flatMap is available to be used.
[1, 2].flatMap((it) => [it, it]); // => [1, 1, 2, 2]
```
- **Polyfill.io**: A service that provides polyfills based on the features and user agents specified in the request.
```js
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
```
## Further reading
- [Polyfill - MDN](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill)
- [Polyfills and transpilers](https://javascript.info/polyfills)
- [Polyfills: How do they work?](https://medium.com/alienbrains/polyfills-how-do-they-work-ea6a12b792b)
- [Polyfill in Javascript](https://www.linkedin.com/pulse/polyfill-javascript-divyansh-singh)
- [Shubham Dutta](https://dev.to/shubhamdutta2000/polyfills-for-javascript-a-full-overview-3f7m)

View File

@ -1,5 +1,5 @@
{
"slug": "what-are-polyfills-for",
"slug": "what-are-javascript-polyfills-for",
"languages": [],
"companies": [],
"premium": false,

View File

@ -1,103 +0,0 @@
---
title: What are polyfills for ?
---
## TL;DR
Polyfills in JavaScript are pieces of code that provide modern functionality to older browsers that lack native support for those features. They bridge the gap between the JavaScript language features and APIs available in modern browsers and the limited capabilities of older browser versions.
**Key Points about Polyfills**
- **Purpose**: To bridge the gap between modern JavaScript features and older browsers.
- **Implementation**: They can be implemented manually or included through libraries.
- **Usage**: They are often used in conjunction with feature detection.
**Common Use Cases for Polyfills**:
- **New JavaScript Methods**: For example, `Array.prototype.includes()`, `Object.assign()`, etc.
- **New APIs**: Such as Fetch API, `Promise`, `IntersectionObserver`, etc.
- **ES6 Features**: Such as `let`, `const`, `arrow functions`, etc.
**Libraries and services for Polyfills**
- `Core-js`: A modular standard library for JavaScript which includes polyfills for a wide range of ECMAScript features.
```js
import 'core-js/stable';
import 'regenerator-runtime/runtime';
```
- `Polyfill.io`: A service that provides polyfills based on the features and user agents specified in the request.
```js
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
```
---
## Polyfills in JavaScript:
Polyfills in JavaScript are pieces of code (usually JavaScript) that provide modern functionality on older browsers that do not natively support it. They enable developers to use newer features of the language and APIs while maintaining compatibility with older environments.
### How Polyfills Work
Polyfills detect if a feature or API is missing in a browser and provide a custom implementation of that feature using existing JavaScript capabilities. This allows developers to write code using the latest JavaScript features and APIs without worrying about browser compatibility issues.
For example, let's consider the `Array.prototype.includes()` method, which determines if an array includes a specific element. This method is not supported in older browsers like `Internet Explorer 11`. To address this, we can use a polyfill:
```js
// Polyfill for Array.prototype.includes()
if (!Array.prototype.includes) {
Array.prototype.includes = function (searchElement) {
for (var i = 0; i < this.length; i++) {
if (this[i] === searchElement) {
return true;
}
}
return false;
};
}
```
By including this polyfill, we can safely use Array.prototype.includes() even in browsers that don't support it natively.
### Implementing Polyfills
- **Identify the missing feature**: Determine if the feature is compatible with the target browsers or detect its presence using feature detection methods like `typeof`, `in`, or `window`.
- **Write the fallback implementation**: Develop the fallback implementation that provides similar functionality, either using a pre-existing polyfill library or pure JavaScript code.
- **Test the polyfill**: Thoroughly test the polyfill to ensure it functions as intended across different contexts and browsers.
- **Implement the polyfill**: Enclose the code that uses the missing feature in an if statement that checks for feature support. If not supported, run the polyfill code instead.
### Considerations
- **Selective Loading**: Polyfills should only be loaded for browsers that need them to optimize performance.
- **Feature Detection**: Perform feature detection before applying a polyfill to avoid overwriting native implementations or applying unnecessary polyfills.
- **Size and Performance**: Polyfills can increase the JavaScript bundle size, so minification and compression techniques should be used to mitigate this impact.
- **Existing Libraries**: Consider using existing libraries and tools that offer comprehensive polyfill solutions for multiple features, handling feature detection, conditional loading, and fallbacks efficiently
### Libraries and services for Polyfills
- `Core-js`: A modular standard library for JavaScript which includes polyfills for a wide range of ECMAScript features.
```js
import 'core-js/stable';
import 'regenerator-runtime/runtime';
```
- `Polyfill.io`: A service that provides polyfills based on the features and user agents specified in the request.
```js
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
```
## Summary
Polyfills are essential for ensuring cross-browser compatibility and enabling the use of modern JavaScript features in older browsers. By understanding how polyfills work and implementing them carefully, developers can write more robust and consistent code across different browser versions.
## Further reading
- [Polyfill - MDN](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill)
- [Polyfills and transpilers](https://javascript.info/polyfills)
- [Polyfills: How do they work?](https://medium.com/alienbrains/polyfills-how-do-they-work-ea6a12b792b)
- [Polyfill in Javascript](https://www.linkedin.com/pulse/polyfill-javascript-divyansh-singh)
- [Shubham Dutta](https://dev.to/shubhamdutta2000/polyfills-for-javascript-a-full-overview-3f7m)

View File

@ -1,284 +0,0 @@
---
title: What are property flags and descriptors?
---
**TL;DR**
In JavaScript, property flags and descriptors manage the behavior and attributes of object properties.
### Property Flags
Property flags are used to specify the behavior of a property. Here are the available flags:
- `writable`: Specifies whether the property can be written to. Default is `true`.
- `enumerable`: Specifies whether the property is enumerable. Default is `true`.
- `configurable`: Specifies whether the property can be deleted or its attributes changed. Default is `true`.
- `value`: Specifies the initial value of the property.
- `get`: Specifies a getter function for the property.
- `set`: Specifies a setter function for the property.
### Property Descriptors
These provide detailed information about an object's property, including its value and flags. They are retrieved using `Object.getOwnPropertyDescriptor()` and set using `Object.defineProperty()`.
### Use Cases
- **Data Validation**: Validate data before setting, like ensuring age is a positive number.
- **Computed Properties**: Derive properties from others, like creating a fullName property from firstName and lastName.
- **Encapsulation**: Control data access with getter and setter methods, ensuring private properties.
- **Inheritance**: Control property inheritance behavior in class hierarchies, setting non-writable or non-configurable properties.
---
In JavaScript, property flags and descriptors are used to manage the behavior and attributes of object properties. These flags and descriptors are essential for understanding how properties are accessed, modified, and inherited.
## Property Flags
Property flags are used to specify the behavior of a property. They are set using the `Object.defineProperty()` method, which allows you to define a property on an object with specific attributes. The available property flags are:
- `writable`: Specifies whether the property can be written to. Default is `true`.
- `enumerable`: Specifies whether the property is enumerable. Default is `true`.
- `configurable`: Specifies whether the property can be deleted or its attributes changed. Default is `true`.
- `value`: Specifies the initial value of the property.
- `get`: Specifies a getter function for the property.
- `set`: Specifies a setter function for the property.
## Property Descriptors
Property descriptors provide detailed information about an object's property, encapsulating its value and flags. They are retrieved using `Object.getOwnPropertyDescriptor()` and set using `Object.defineProperty()`
```js
let user = { name: 'John Doe' };
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor); // Output: {value: "John Doe", writable: true, enumerable: true, configurable: true}
```
## Manipulating property flags
### `writable` Flag
The `writable` flag specifies whether a property can be written to. When `writable` is `false`, trying to assign value to the property fails silently in non-strict mode, and it throws a `TypeError` in strict mode.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
writable: false,
value: 'John Doe',
});
console.log(obj.name); // Output: John Doe
obj.name = 'Jane Doe'; // TypeError: Cannot assign to read only property 'name' of object '#<Object>'
```
### `enumerable` Flag
The `enumerable` flag specifies whether a property is enumerable. The `enumerable flag` is set to `true`, which means the property is visible in a `for...in` loop.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
enumerable: false,
value: 'John Doe',
});
for (const prop in obj) {
console.log(prop); // Output: nothing
}
const obj1 = {};
Object.defineProperty(obj1, 'name', {
enumerable: true,
value: 'John Doe',
});
for (const prop in obj1) {
console.log(prop); // Output: name
}
```
## `configurable` Flag
The `configurable` flag specifies whether a property can be deleted or its attributes changed. When `configurable` is `false`, trying to delete or change the property fails silently in non-strict mode, and it throws a `TypeError` in strict mode.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
configurable: false,
value: 'John Doe',
});
delete obj.name; // Output: TypeError: Cannot delete property 'name' of #<Object>
```
## `value` Flag
The `value` flag specifies the initial value of a property.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
value: 'John Doe',
});
console.log(obj.name); // Output: John Doe
```
## `get` Flag
The `get` flag specifies a getter function for a property.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
get() {
return 'John Doe';
},
});
console.log(obj.name); // Output: John Doe
```
## `set` Flag
The `set` flag specifies a setter function for a property.
```js
const obj = {};
Object.defineProperty(obj, 'name', {
set(value) {
if (value.length < 3) {
throw new Error('Name must have more than 3 characters');
}
console.log(`Setting name to ${value}`);
},
});
obj.name = 'Jane Doe'; // Output: Setting name to Jane Doe
obj.name = 'Ja'; // Error: Name must have more than 3 characters
```
## Use cases
### Data Validation
You can use property descriptors to validate data before it is set on an object. For example, you can create a `person` object with an `age` property that has a setter function that checks if the `age` is a valid number:
```js
const person = {};
Object.defineProperty(person, 'age', {
set(value) {
if (typeof value !== 'number' || value < 0) {
throw new Error('Age must be a positive number');
}
this._age = value;
},
get() {
return this._age;
},
});
person.age = 30;
console.log(person.age); // Output: 30
person.age = -10; // Output: Error: Age must be a positive number
```
### Computed Properties
You can use property descriptors to create computed properties that are derived from other properties on the object. For example, you can create a `fullName` property that is derived from `firstName` and `lastName` properties:
```js
const person = {
firstName: 'John',
lastName: 'Doe',
};
Object.defineProperty(person, 'fullName', {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
[this.firstName, this.lastName] = value.split(' ');
},
});
console.log(person.fullName); // Output: John Doe
person.fullName = 'Jane Smith';
console.log(person.firstName); // Output: Jane
console.log(person.lastName); // Output: Smith
```
### Encapsulation
You can use property descriptors to encapsulate data and control access to it. For example, you can create a `BankAccount` class with a `balance` property that is only accessible through getter and setter methods:
```js
class BankAccount {
#balance = 0;
get balance() {
return this.#balance;
}
deposit(amount) {
this.#balance += amount;
}
withdraw(amount) {
if (amount <= this.#balance) {
this.#balance -= amount;
} else {
console.log('Insufficient funds');
}
}
}
const account = new BankAccount();
account.deposit(1000);
console.log(account.balance); // Output: 1000
account.withdraw(500);
console.log(account.balance); // Output: 500
account.#balance = 10000; // Error: Private field '#balance' must be declared in an enclosing class
```
### Inheritance
You can use property descriptors to control how properties are inherited in a class hierarchy. For example, you can create a `Vehicle` class with a make property that is non-writable and non-configurable, and a `Car` class that inherits from `Vehicle`:
```js
class Vehicle {
constructor(make) {
Object.defineProperty(this, 'make', {
value: make,
writable: false,
configurable: false,
});
}
}
class Car extends Vehicle {
constructor(make, model) {
super(make);
this.model = model;
}
}
const car = new Car('Toyota', 'Camry');
console.log(car.make); // Output: Toyota
car.make = 'Honda'; // No effect
```
## Further reading
- [Object.defineProperty() | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty)
- [Property flags and descriptors | Javascript.info](https://javascript.info/property-descriptors)
- [JavaScript: Property Flags and Descriptors | W3docs.com](https://www.w3docs.com/learn-javascript/property-flags-and-descriptors.html)

View File

@ -1,14 +1,14 @@
---
title: What are `Symbols` used for ?
title: What are `Symbol`s used for?
---
## TL;DR
`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. These values can be created using `Symbol(...)` function, and each `Symbol` value is guaranteed to be unique, even if they have the same description. `Symbol` properties are not enumerable in `for...in` loops or `Object.keys()`, making them suitable for creating private/internal object state.
`Symbol`s 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. These values can be created using `Symbol(...)` function, and each `Symbol` value is guaranteed to be unique, even if they have the same key/description. `Symbol` properties are not enumerable in `for...in` loops or `Object.keys()`, making them suitable for creating private/internal object state.
```js
let sym1 = Symbol();
let sym2 = Symbol('description');
let sym2 = Symbol('myKey');
console.log(typeof sym1); // "symbol"
console.log(sym1 === sym2); // false, because each symbol is unique
@ -20,27 +20,27 @@ obj[sym] = 'value';
console.log(obj[sym]); // "value"
```
> The `Symbol(..)` function must be called without the `new` keyword.
**Note**: The `Symbol()` function must be called without the `new` keyword. It is not exactly a constructor because it can only be called as a function instead of with `new Symbol()`.
---
## `Symbols` in JavaScript
## `Symbol`s in JavaScript
Symbols in JavaScript are a unique and immutable data type used primarily for object property keys to avoid name collisions.
### Key Characteristics
## 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().
- **Non-enumerable**: Symbol properties are not included in for...in loops or Object.keys().
### Creating `Symbol`
## Creating `Symbol`s
You can create a `Symbol` using the `Symbol()` function:
`Symbol`s can be created using the `Symbol()` function:
```js
let sym1 = Symbol();
let sym2 = Symbol('description');
const sym1 = Symbol();
const sym2 = Symbol('uniqueKey');
console.log(typeof sym1); // "symbol"
console.log(sym1 === sym2); // false, because each symbol is unique
@ -48,47 +48,58 @@ console.log(sym1 === sym2); // false, because each symbol is unique
> The `Symbol(..)` function must be called without the `new` keyword.
### Using `Symbols` as `object` property keys
## Using `Symbol`s as `object` property keys
`Symbols` can be used to add properties to an object without risk of name collision:
`Symbol`s can be used to add properties to an object without risk of name collision:
```js
let obj = {};
let sym = Symbol('uniqueKey');
const obj = {};
const sym = Symbol('uniqueKey');
obj[sym] = 'value';
console.log(obj[sym]); // "value"
```
### `Symbol` are not enumerable
## `Symbol`s are not enumerable
- `Symbol` properties are not included in `for...in` loops or` Object.keys()`.
- This makes them suitable for creating private/internal object state.
- You can use` Object.getOwnPropertySymbols(obj)` to get all symbol properties of an object
- Use` Object.getOwnPropertySymbols(obj)` to get all symbol properties on an object.
```js
const mySymbol = Symbol('privateProperty');
const obj = {
name: 'John',
[mySymbol]: 42,
};
console.log(Object.keys(obj)); // Output: ['name']
console.log(obj[mySymbol]); // Output: 42
```
### 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 on. This allows you to reuse `symbols` across different parts of your codebase or even across different code bases.
You can create global `Symbol`s 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 `Symbol`s across different parts of your code base or even across different code bases.
```js
let globalSym1 = Symbol.for('globalKey');
let globalSym2 = Symbol.for('globalKey');
const globalSym1 = Symbol.for('globalKey');
const globalSym2 = Symbol.for('globalKey');
console.log(globalSym1 === globalSym2); // true
let key = Symbol.keyFor(globalSym1);
const key = Symbol.keyFor(globalSym1);
console.log(key); // "globalKey"
```
## Well-known `Symbol`
JavaScript includes several built-in `symbols`, referred as `well-known symbols`.
JavaScript includes several built-in `Symbol`s, referred as well-known `Symbol`s.
- **Symbol.iterator**: Defines the default `iterator` for an `object`.
- **Symbol.toStringTag**: Used to create a string description for an `object`.
- **Symbol.hasInstance**: Used to determine if an `object` is an instance of a `constructor`.
- **`Symbol.iterator`**: Defines the default `iterator` for an object.
- **`Symbol.toStringTag`**: Used to create a string description for an object.
- **`Symbol.hasInstance`**: Used to determine if an object is an instance of a constructor.
**`Symbol.iterator`**:
### `Symbol.iterator`
```js
let iterable = {
@ -111,7 +122,7 @@ for (let value of iterable) {
}
```
**`Symbol.toStringTag`**:
### `Symbol.toStringTag`
```js
let myObj = {
@ -127,7 +138,7 @@ Symbols are a powerful feature in JavaScript, especially useful for creating uni
## Further reading
- [Symbol- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
- [Symbol - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
- [Symbol type](https://javascript.info/symbol)
- [A quick overview of JavaScript symbols](https://www.freecodecamp.org/news/how-did-i-miss-javascript-symbols-c1f1c0e1874a/)
- [Symbol Values - You Don't Know JS Yet](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/types-grammar/ch1.md#symbol-values)

View File

@ -4,21 +4,16 @@ title: What are the benefits of using spread syntax and how is it different from
## TL;DR
**Spread syntax** allows you to expand an iterable (such as an array or string) into individual elements. This is often used to create new arrays or objects by combining existing ones.
**Spread syntax** (`...`) allows an iterable (like an array or string) to be expanded into individual elements. This is often used as a convenient and modern way to create new arrays or objects by combining existing ones.
```js
// Spreading an array
const numbers = [1, 2, 3];
const newNumbers = [...numbers, 4, 5];
console.log(newNumbers); // Output: [1, 2, 3, 4, 5]
| Operation | Traditional | Spread |
| -------------- | ------------------------------- | ---------------------- |
| Array cloning | `arr.slice()` | `[...arr]` |
| Array merging | `arr1.concat(arr2)` | `[...arr1, ...arr2]` |
| Object cloning | `Object.assign({}, obj)` | `{ ...obj }` |
| Object merging | `Object.assign({}, obj1, obj2)` | `{ ...obj1, ...obj2 }` |
// Spreading an object
const person = { name: 'John', age: 30 };
const newPerson = { ...person, city: 'New York' };
console.log(newPerson); // Output: { name: 'John', age: 30, city: 'New York' }
```
**Rest syntax** is just the opposite of what Spread syntax does. It collects a variable number of arguments into an array. This is often used in function parameters to handle a dynamic number of arguments.
**Rest syntax** is the opposite of what spread syntax does. It collects a variable number of arguments into an array. This is often used in function parameters to handle a dynamic number of arguments.
```js
// Using rest syntax in a function
@ -31,39 +26,62 @@ console.log(sum(1, 2, 3)); // Output: 6
---
## Spread Syntax
## Spread syntax
ES2015's spread syntax is very useful when coding in a functional paradigm as we can easily create copies of arrays or objects without resorting to `Object.create`, `slice`, or a library function. This language feature is used often in Redux and RxJS projects.
ES2015's spread syntax is very useful when coding in a functional paradigm as we can easily create copies of / merge arrays or objects without resorting to `Object.create`, `Object.assign`, `Array.prototype.slice`, or a library function. This language feature is used often in Redux and RxJS projects.
### Copying arrays/objects
The spread syntax provides a concise way to create copies of arrays or objects without modifying the originals. This is useful for creating immutable data structures. However do note that arrays copied via the spread operator are shallowly-copied.
```js
// Example 1: Merging arrays
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let mergedArray = [...array1, ...array2];
console.log(mergedArray); // Output: [1, 2, 3, 4, 5, 6]
// Example 2: Adding elements to the end of an array
let array = [1, 2, 3];
let newElement = 4;
let updatedArray = [...array, newElement];
console.log(updatedArray); // Output: [1, 2, 3, 4]
// Example 3: Creating a new array from an existing one
let array3 = [1, 2, 3];
let newArray = [...array3];
// Copying arrays
const array = [1, 2, 3];
const newArray = [...array];
console.log(newArray); // Output: [1, 2, 3]
// Example 4: Creating a new object from an existing one
const person = {
name: 'Todd',
age: 29,
};
const copyOfTodd = { ...person };
console.log(copyOfTodd); // Output: {name: "Todd", age: 29}
// Copying objects
const obj = { name: 'John', age: 30 };
const newObj = { ...person, city: 'New York' };
console.log(newObj); // Output: { name: 'John', age: 30, city: 'New York' }
```
Only iterable values like `Array` and `String`, can be spread in array and trying to do so will result into TypeError. On the other hand, arrays can be spread into objects.
### Merging arrays/objects
The spread syntax allows you to merge arrays or objects by spreading their elements/properties into a new array or object.
```js
// Merging arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const mergedArray = [...arr1, ...arr2];
console.log(mergedArray); // Output: [1, 2, 3, 4, 5, 6]
// Merging objects
const obj1 = {
foo: 'bar',
};
const obj2 = {
qux: 'baz',
};
const merged = { ...obj1, ...obj2 };
console.log(copyOfTodd); // Output: { foo: "bar", qux: "baz" }
```
### Passing arguments to functions
Use the spread syntax to pass an array of values as individual arguments to a function, avoiding the need for `apply()`.
```js
const numbers = [1, 2, 3];
Math.max(...numbers); // Same as Math.max(1, 2, 3)
```
### Array vs object spreads
Only iterable values like `Array`s and `String`s can be spread in an array. Trying to spread non-iterables will result in a `TypeError`.
Spreading object into array:
@ -75,36 +93,37 @@ const person = {
const array = [...person]; // Error: Uncaught TypeError: person is not iterable
```
Spreading array into object:
On the other hand, arrays can be spread into objects.
```js
const array = [1, 2, 3];
const obj = { ...array }; // { 0: 1, 1: 2, 2: 3 }
```
## Rest Syntax
## Rest syntax
ES2015's rest syntax offers a shorthand for including an arbitrary number of arguments to be passed to a function. It is like an inverse of the spread syntax, taking data and stuffing it into an array rather than unpacking an array of data, and it works in function arguments, as well as in array and object destructuring assignments.
The rest syntax (`...`) in JavaScript allows you to represent an indefinite number of elements as an array or object. It is like an inverse of the spread syntax, taking data and stuffing it into an array rather than unpacking an array of data, and it works in function arguments, as well as in array and object destructuring assignments.
### Rest parameters in functions
The rest syntax can be used in function parameters to collect all remaining arguments into an array. This is particularly useful when you don't know how many arguments will be passed to the function.
```js
// Example 1: To gather all arguments into array `numbers`
function addFiveToABunchOfNumbers(...numbers) {
return numbers.map((x) => x + 5);
}
const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10);
console.log(result); // Output: [9, 10, 11, 12, 13, 14, 15]
```
// Example 2: Creating a new array from the remaining elements
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
Provides a cleaner syntax than using the `arguments` object, which is unsupported for arrow functions and represents **all** arguments whereas the usage of the rest syntax below allows `remaining` to represent the 3rd argument and beyond.
// Example 3: Creating a new object from the remaining properties
const { e, f, ...others } = {
e: 1,
f: 2,
g: 3,
h: 4,
}; // e: 1, f: 2, others: { g: 3, h: 4 }
```js
const [first, second, ...remaining] = [1, 2, 3, 4, 5];
console.log(first); // Output: 1
console.log(second); // Output: 2
console.log(remaining); // Output: [3, 4, 5]
```
Note that the rest parameters must be at the end. The rest parameters gather all remaining arguments, so the following does not make sense and causes an error:
@ -115,6 +134,27 @@ function addFiveToABunchOfNumbers(arg1, ...numbers, arg2) {
}
```
### Array destructuring
The rest syntax can be used in array destructuring to collect the remaining elements into a new array.
```js
const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4]
```
### Object destructuring
The rest syntax can be used in object destructuring to collect the remaining properties into a new object.
```js
const { e, f, ...others } = {
e: 1,
f: 2,
g: 3,
h: 4,
}; // e: 1, f: 2, others: { g: 3, h: 4 }
```
## Further Reading
- [Spread syntax | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)

View File

@ -1,12 +1,10 @@
---
title: What are the differences between ES2015 class and ES5 function constructors?
title: What are the differences between ES2015 classes and ES5 function constructors?
---
## TL;DR
ES6 introduces a new way of creating classes, which provides a more intuitive and concise way to define and work with objects and inheritance compared to the ES5 function constructor syntax.
Let's first look at example of each:
ES2015 introduces a new way of creating classes, which provides a more intuitive and concise way to define and work with objects and inheritance compared to the ES5 function constructor syntax. Here's an example of each:
```js
// ES5 Function Constructor
@ -22,9 +20,7 @@ class Person {
}
```
For simple constructors, they look pretty similar.
The main difference in the constructor comes when using inheritance. If we want to create a `Student` class that subclasses `Person` and add a `studentId` field, this is what we have to do in addition to the above.
For simple constructors, they look pretty similar. The main difference in the constructor comes when using inheritance. If we want to create a `Student` class that subclasses `Person` and add a `studentId` field, this is what we have to do in addition to the above.
```js
// ES5 Function Constructor
@ -50,9 +46,9 @@ class Student extends Person {
It's much more verbose to use inheritance in ES5 and the ES2015 version is easier to understand and remember.
### Comparison of ES6 Class and ES5 Function constructor
**Comparison of ES5 function constructors vs ES2015 classes**
| Feature | ES5 Function Constructor | ES6 Class |
| Feature | ES5 Function Constructor | ES2015 Class |
| --- | --- | --- |
| Syntax | Uses function constructors and prototypes | Uses `class` keyword |
| Constructor | Function with properties assigned using `this` | `constructor` method inside the class |
@ -63,13 +59,13 @@ It's much more verbose to use inheritance in ES5 and the ES2015 version is easie
---
## ES5 Function constructor vs ES6 Classes
## ES5 function constructor vs ES2015 classes
ES6 classes and ES5 function constructors are two different ways of defining `classes` in JavaScript. They both serve the same purpose, but they have different syntax and behavior.
ES5 function constructors and ES2015 classes are two different ways of defining classes in JavaScript. They both serve the same purpose, but they have different syntax and behavior.
### ES5 Function Constructor
### ES5 function constructors
In ES5, you define a class-like structure using a function constructor and prototypes. Heres an example:
In ES5, you define a class-like structure using a function constructor and prototypes. Here's an example:
```js
// ES5 Function Constructor
@ -89,12 +85,12 @@ var person1 = new Person('John', 30);
person1.greet(); // Hello, my name is John and I am 30 years old.
```
### ES6 Class
### ES2015 classes
ES6 introduced the class syntax, which simplifies the definition of classes and supports more features such as static methods and subclassing. Heres the same example using ES6:
ES2015 introduced the `class` syntax, which simplifies the definition of classes and supports more features such as static methods and subclassing. Here's the same example using ES2015:
```js
// ES6 Class
// ES2015 Class
class Person {
constructor(name, age) {
this.name = name;
@ -118,12 +114,12 @@ person1.greet(); // Hello, my name is John and I am 30 years old.
1. **Syntax and Readability**:
- **ES5**: Uses function constructors and prototypes, which can be less intuitive and harder to read.
- **ES6**: Uses the `class` keyword, making the code more concise and easier to understand.
- **ES2015**: Uses the `class` keyword, making the code more concise and easier to understand.
2. **Static Methods**:
- **ES5**: Static methods are added directly to the constructor function.
- **ES6**: Static methods are defined within the class using the `static` keyword.
- **ES2015**: Static methods are defined within the class using the `static` keyword.
```js
// ES5
@ -138,7 +134,7 @@ person1.greet(); // Hello, my name is John and I am 30 years old.
Person.sayHi(); // Hi!
// ES6
// ES2015
class Person {
static sayHi() {
console.log('Hi!');
@ -150,7 +146,7 @@ person1.greet(); // Hello, my name is John and I am 30 years old.
3. **Inheritance**
- **ES5**: Inheritance is achieved using `Object.create()` and manually setting the prototype chain.
- **ES6**: Inheritance is much simpler and more intuitive with the extends keyword.
- **ES2015**: Inheritance is much simpler and more intuitive with the extends keyword.
```js
// ES5 Inheritance
@ -187,9 +183,9 @@ person1.greet(); // Hello, my name is John and I am 30 years old.
student1.greet(); // Hello, my name is Alice and I am 20 years old.
student1.study(); // Alice is studying.
// ES6 Inheritance
// ES2015 Inheritance
// ES6 Class
// ES2015 Class
class Person {
constructor(name, age) {
this.name = name;
@ -219,18 +215,18 @@ person1.greet(); // Hello, my name is John and I am 30 years old.
student1.study(); // Alice is studying.
```
4. Super Calls:
4. `super` calls:
- **ES5**: Manually call the parent constructor function.
- **ES6**: Use the `super` keyword to call the parent class's constructor and methods.
- **ES2015**: Use the `super` keyword to call the parent class's constructor and methods.
### Conclusion
While both ES5 and ES6 approaches can achieve the same functionality, ES6 classes provide a clearer and more concise way to define and work with object-oriented constructs in JavaScript. This makes the code easier to write, read, and maintain. If you are working with modern JavaScript, it is generally recommended to use ES6 classes over ES5 function constructors
While both ES5 and ES2015 approaches can achieve the same functionality, ES2015 classes provide a clearer and more concise way to define and work with object-oriented constructs in JavaScript, which makes the code easier to write, read, and maintain. If you are working with modern JavaScript, it is generally recommended to use ES2015 classes over ES5 function constructors.
## Resources
- [Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)
- [Inheritance- MDN ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#inheritance)
- [The Secret Life Of Objects](https://eloquentjavascript.net/06_object.html)
- [ES6 vs ES5](https://www.educative.io/courses/learn-object-oriented-programming-in-javascript/es6-vs-es5)
- [ES2015 vs ES5](https://www.educative.io/courses/learn-object-oriented-programming-in-javascript/es2015-vs-es5)

View File

@ -0,0 +1,146 @@
---
title: What are the differences between `Map`/`Set` vs `WeakMap`/`WeakSet`?
---
## TL;DR
The primary difference between `Map`/`Set` and `WeakMap`/`WeakSet` in JavaScript lies in how they handle keys. Here's a breakdown:
**`Map` vs. `WeakMap`**
`Map`s allows any data type (strings, numbers, objects) as keys. The key-value pairs remain in memory as long as the `Map` object itself is referenced. Thus they are suitable for general-purpose key-value storage where you want to maintain references to both keys and values. Common use cases include storing user data, configuration settings, or relationships between objects.
`WeakMap`s only allows objects as keys. However, these object keys are held weakly. This means the garbage collector can remove them from memory even if the `WeakMap` itself still exists, as long as there are no other references to those objects. `WeakMap`s are ideal for scenarios where you want to associate data with objects without preventing those objects from being garbage collected. This can be useful for things like:
- Caching data based on objects without preventing garbage collection of the objects themselves.
- Storing private data associated with DOM nodes without affecting their lifecycle.
**`Set` vs. `WeakSet`**
Similar to `Map`, `Set`s allow any data type as keys. The elements within a `Set` must be unique. `Set`s are useful for storing unique values and checking for membership efficiently. Common use cases include removing duplicates from arrays or keeping track of completed tasks.
On the other hand, `WeakSet` only allows objects as elements, and these object elements are held weakly, similar to `WeakMap` keys. `WeakSet`s are less commonly used, but applicable when you want a collection of unique objects without affecting their garbage collection. This might be necessary for:
- Tracking DOM nodes that have been interacted with without affecting their memory management.
- Implementing custom object weak references for specific use cases.
**Here's a table summarizing the key differences:**
| Feature | Map | WeakMap | Set | WeakSet |
| --- | --- | --- | --- | --- |
| Key Types | Any data type | Objects (weak references) | Any data type (unique) | Objects (weak references, unique) |
| Garbage Collection | Keys and values are not garbage collected | Keys can be garbage collected if not referenced elsewhere | Elements are not garbage collected | Elements can be garbage collected if not referenced elsewhere |
| Use Cases | General-purpose key-value storage | Caching, private DOM node data | Removing duplicates, membership checks | Object weak references, custom use cases |
**Choosing between them**
- Use `Map` and `Set` for most scenarios where you need to store key-value pairs or unique elements and want to maintain references to both the keys/elements and the values.
- Use `WeakMap` and `WeakSet` cautiously in specific situations where you want to associate data with objects without affecting their garbage collection. Be aware of the implications of weak references and potential memory leaks if not used correctly.
---
## `Map`/`Set` vs `WeakMap`/`WeakSet`
The key differences between `Map`/`Set` and `WeakMap`/`WeakSet` in JavaScript are:
1. **Key types**: `Map` and `Set` can have keys of any type (objects, primitive values, etc.), while `WeakMap` and `WeakSet` can only have objects as keys. Primitive values like strings or numbers are not allowed as keys in `WeakMap` and `WeakSet`.
2. **Memory management**: The main difference lies in how they handle memory. `Map` and `Set` have strong references to their keys and values, which means they will prevent garbage collection of those values. On the other hand, `WeakMap` and `WeakSet` have weak references to their keys (objects), allowing those objects to be garbage collected if there are no other strong references to them.
3. **Key enumeration**: Keys in `Map` and `Set` are enumerable (can be iterated over), while keys in `WeakMap` and `WeakSet` are not enumerable. This means you cannot get a list of keys or values from a `WeakMap` or `WeakSet`.
4. **`size` property**: `Map` and `Set` have a `size` property that returns the number of elements, while `WeakMap` and `WeakSet` do not have a `size` property because their size can change due to garbage collection.
5. **Use cases**: `Map` and `Set` are useful for general-purpose data structures and caching, while `WeakMap` and `WeakSet` are primarily used for storing metadata or additional data related to objects, without preventing those objects from being garbage collected.
`Map` and `Set` are regular data structures that maintain strong references to their keys and values, while `WeakMap` and `WeakSet` are designed for scenarios where you want to associate data with objects without preventing those objects from being garbage collected when they are no longer needed.
## Use cases of `WeakMap` and `WeakSet`
### Tracking active users
In a chat application, you might want to track which user objects are currently active without preventing garbage collection when the user logs out or the session expires. We use a `WeakSet` to track active user objects. When a user logs out or their session expires, the user object can be garbage-collected if there are no other references to it.
```js
const activeUsers = new WeakSet();
// Function to mark a user as active
function markUserActive(user) {
activeUsers.add(user);
}
// Function to check if a user is active
function isUserActive(user) {
return activeUsers.has(user);
}
// Example usage
let user1 = { id: 1, name: 'Alice' };
let user2 = { id: 2, name: 'Bob' };
markUserActive(user1);
markUserActive(user2);
console.log(isUserActive(user1)); // true
console.log(isUserActive(user2)); // true
// Simulate user logging out
user1 = null;
// user1 is now eligible for garbage collection
console.log(isUserActive(user1)); // false
```
### Detecting circular references
`WeakSet` is provides a way of guarding against circular data structures by tracking which objects have already been processed.
```js
// Create a WeakSet to track visited objects
const visited = new WeakSet();
// Function to traverse an object recursively
function traverse(obj) {
// Check if the object has already been visited
if (visited.has(obj)) {
return;
}
// Add the object to the visited set
visited.add(obj);
// Traverse the object's properties
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
let value = obj[prop];
if (typeof value === 'object' && value !== null) {
traverse(value);
}
}
}
// Process the object
console.log(obj);
}
// Create an object with a circular reference
const obj = {
name: 'John',
age: 30,
friends: [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 28 },
],
};
// Create a circular reference
obj.self = obj;
// Traverse the object
traverse(obj);
```
## Further reading
- [`Map` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
- [`WeakMap` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
- [`Set` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
- [`WeakSet` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet)
- [`Map` and `Set` | Javascript.info](https://javascript.info/map-set)
- [`WeakMap` and `WeakSet` | Javascript.info](https://javascript.info/weakmap-weakset)

View File

@ -1,5 +1,5 @@
{
"slug": "what-the-differences-between-map-set-and-weakmap-weakset",
"slug": "what-are-the-differences-between-map-set-and-weakmap-weakset",
"languages": [],
"companies": [],
"premium": false,

View File

@ -1,22 +1,22 @@
---
title: What are the various data types in javascript ?
title: What are the various data types in JavaScript?
---
## TL;DR
In JavaScript, data types can be categorized into `primitive` and `non-primitive` types:
**Primitive data type**
**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.
- **Symbol**: A unique and immutable value used as object property keys. Read more in our [deep dive on `Symbol`s](/questions/quiz/what-are-symbols-used-for)
- **BigInt**: Represents integers with arbitrary precision.
**Non-Primitive (Reference) Data Types**
**Non-primitive (Reference) data types**
- **Object**: Used to store collections of data.
- **Array**: An ordered collection of data.
@ -26,13 +26,13 @@ In JavaScript, data types can be categorized into `primitive` and `non-primitive
- **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.
The primitive types store a single value, while non-primitive types can store collections of data or complex entities.
---
## Data types in JavaScript
JavaScript, like many programming languages, has a variety of data types to represent different kinds of data. The main data types in JavaScript can be divided into two categories: `primitive` and `non-primitive (reference)` types.
JavaScript, like many programming languages, has a variety of data types to represent different kinds of data. The main data types in JavaScript can be divided into two categories: primitive and non-primitive (reference) types.
### Primitive data types
@ -85,7 +85,7 @@ let bigNumber = BigInt(9007199254740991);
let anotherBigNumber = 1234567890123456789012345678901234567890n;
```
### `Non-primitive` (reference) data types
### Non-primitive (reference) data types
1. **Object**: It is used to store collections of data and more complex entities. `Objects` are created using curly braces `{}`.
@ -141,18 +141,9 @@ set.add(1);
set.add(2);
```
## Pitfalls
## Determining data types
### Type coercion:
JavaScript often performs type coercion, converting values from one type to another, which can lead to unexpected results.
```js
let result = '5' + 5; // '55' (string concatenation)
let sum = '5' - 2; // 3 (numeric subtraction)
```
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.
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.
```js
console.log(typeof 42); // "number"
@ -167,9 +158,22 @@ console.log(typeof []); // "object"
console.log(typeof function () {}); // "function"
```
## Pitfalls
### Type coercion
JavaScript often performs type coercion, converting values from one type to another, which can lead to unexpected results.
```js
let result = '5' + 2; // '52' (string concatenation)
let difference = '5' - 2; // 3 (numeric subtraction)
```
In the first example, since strings can be concatenated with the `+` operator, the number is converted into a string and the two strings are concatenated together. In the second example, strings cannot work with the minus operator (`-`), but two numbers can be minused, so the string is first converted into a number and the result is the difference.
## Further reading
- [JavaScript data types and data structures - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures)
- [JavaScript guide: Data types](https://www.linkedin.com/pulse/javascript-guide-data-types-mila-mirovi%C4%87-jykmf)
- [JavaScript data types](https://www.programiz.com/javascript/data-types)
- [Data types - javascript.info](https://javascript.info/types)
- [JavaScript data types](https://www.programiz.com/javascript/data-types)

View File

@ -6,20 +6,21 @@ title: What are the various ways to create objects in JavaScript?
Creating objects in JavaScript offers several methods:
- **Object Literals**: Simplest, most popular. Define key-value pairs within curly braces.
- **`Object()` Constructor**: Use `new Object()` with dot notation to add properties.
- **Constructor Functions**: Define blueprints for objects using functions, creating instances with `new`.
- **ES6 Classes**: Structured syntax similar to other languages, using `class` and `constructor` keywords.
- **`Object.create()` Method**: Create new objects using existing objects as prototypes, inheriting properties and methods.
- **`Object.assign()` Method**: Copy properties from source objects to target objects using Object.assign().
- **Object literals (`{}`)**: Simplest and most popular approach. Define key-value pairs within curly braces.
- **`Object()` constructor**: Use `new Object()` with dot notation to add properties.
- **`Object.create()`**: Create new objects using existing objects as prototypes, inheriting properties and methods.
- **Constructor functions**: Define blueprints for objects using functions, creating instances with `new`.
- **ES2015 classes**: Structured syntax similar to other languages, using `class` and `constructor` keywords.
---
## Objects in JavaScript
Creating objects in JavaScript involves several methods. Here are the various ways to create objects in JavaScript:
## Object Literals
## Object literals (`{}`)
This is the simplest and most popular way to create objects in JavaScript. It involves defining a collection of key-value pairs within curly braces ({}). It can be used when you need to create a single object with a fixed set of properties.
This is the simplest and most popular way to create objects in JavaScript. It involves defining a collection of key-value pairs within curly braces (`{}`). It can be used when you need to create a single object with a fixed set of properties.
```js
const person = {
@ -30,7 +31,7 @@ const person = {
};
```
## `Object()` contructor
## `Object()` constructor
This method involves using the `new` keyword with the built-in `Object` constructor to create an object. You can then add properties to the object using dot notation. It can be used when you need to create an object from a primitive value or to create an empty object.
@ -40,53 +41,6 @@ person.firstName = 'John';
person.lastName = 'Doe';
```
## Constructor Functions
Constructor functions are used to create reusable blueprints for objects. They define the properties and behaviors shared by all objects of that type. You use the `new` keyword to create instances of the object. It can be used when you need to create multiple objects with similar properties and methods.
```js
// Constructor Function
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function () {
console.log(
`Hello, my name is ${this.name} and I'm ${this.age} years old.`,
);
};
}
const person1 = new Person('John', 30);
const person2 = new Person('Alice', 25);
person1.greet(); // Output: Hello, my name is John and I'm 30 years old.
person2.greet(); // Output: Hello, my name is Alice and I'm 25 years old.
```
## ES6 Classes
Classes provide a more structured and familiar syntax (similar to other programming languages) for creating objects. They define a blueprint and use methods to interact with the object's properties. It can be used when you need to create complex objects with inheritance and encapsulation.
```js
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet = function () {
console.log(
`Hello, my name is ${this.name} and I'm ${this.age} years old.`,
);
};
}
const person1 = new Person('John', 30);
const person2 = new Person('Alice', 25);
person1.greet(); // Output: Hello, my name is John and I'm 30 years old.
person2.greet(); // Output: Hello, my name is Alice and I'm 25 years old.
```
## `Object.create()` Method
This method allows you to create a new object using an existing object as a prototype. The new object inherits properties and methods from the prototype object. It can be used when you need to create a new object with a specific prototype.
@ -108,23 +62,55 @@ person.age = 30;
person.greet(); // Output: Hello, my name is John and I'm 30 years old.
```
## `Object.assign()` Method
An object with a prototype can be created by doing `Object.create(null)`.
This method involves using the `Object.assign()` method to copy properties from a source object to a target object. It can be used when you need to merge properties from multiple objects.
## ES2015 classes
Classes provide a more structured and familiar syntax (similar to other programming languages) for creating objects. They define a blueprint and use methods to interact with the object's properties. It can be used when you need to create complex objects with inheritance and encapsulation.
```js
const person1 = {
firstName: 'John',
lastName: 'Doe',
age: 50,
eyeColor: 'blue',
};
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet = function () {
console.log(
`Hello, my name is ${this.name} and I'm ${this.age} years old.`,
);
};
}
const person2 = { firstName: 'Anne', lastName: 'Smith' };
const person1 = new Person('John', 30);
const person2 = new Person('Alice', 25);
const person = Object.assign({}, person1, person2);
person1.greet(); // Output: Hello, my name is John and I'm 30 years old.
person2.greet(); // Output: Hello, my name is Alice and I'm 25 years old.
```
console.log(person); // Output: { firstName: 'Anne', lastName: 'Smith', age: 50, eyeColor: 'blue' }
## Constructor functions
Constructor functions are used to create reusable blueprints for objects. They define the properties and behaviors shared by all objects of that type. You use the `new` keyword to create instances of the object. It can be used when you need to create multiple objects with similar properties and methods.
However, now that ES2015 classes are readily supported in modern browsers, there's little reason to use constructor functions to create objects.
```js
// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function () {
console.log(
`Hello, my name is ${this.name} and I'm ${this.age} years old.`,
);
};
}
const person1 = new Person('John', 30);
const person2 = new Person('Alice', 25);
person1.greet(); // Output: Hello, my name is John and I'm 30 years old.
person2.greet(); // Output: Hello, my name is Alice and I'm 25 years old.
```
## Further reading
@ -132,4 +118,3 @@ console.log(person); // Output: { firstName: 'Anne', lastName: 'Smith', age: 50,
- [`Object()` constructor | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/Object)
- [`new` keyword | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new)
- [`Object.create()` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)
- [`Object.assign()` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

View File

@ -51,7 +51,7 @@ Workers in JavaScript are a way to run scripts in background threads, separate f
#### Creating a Web Worker
To create a web worker, you need a separate JavaScript file that contains the code for the worker. Heres an example:
To create a web worker, you need a separate JavaScript file that contains the code for the worker. Here's an example:
**main.js (main script)**

View File

@ -8,30 +8,29 @@ In the book ["You Don't Know JS"](https://github.com/getify/You-Dont-Know-JS/tre
> Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope
In simple terms, functions have access to variables that were in their scope at the time of their creation. This is what we call the function's `lexical scope`. A closure is a function that retains access to these variables even after the outer function has finished executing. This is like the function has a `memory` of its original environment.
In simple terms, functions have access to variables that were in their scope at the time of their creation. This is what we call the function's lexical scope. A closure is a function that retains access to these variables even after the outer function has finished executing. This is like the function has a memory of its original environment.
```js
function outerFunction() {
const outerVar = 'I am from the outer function';
const outerVar = 'I am outside of innerFunction';
function innerFunction() {
console.log(outerVar); // innerFunction can still access outerVar
console.log(outerVar); // `innerFunction` can still access `outerVar`.
}
return innerFunction;
}
const closure = outerFunction(); // closure now holds a reference to innerFunction
const inner = outerFunction(); // `inner` now holds a reference to `innerFunction`.
closure(); // "I am from the outer function"
// Even though outerFunction has completed execution closure still have access to variables defined inside outer function
inner(); // "I am outside of innerFunction"
// Even though `outerFunction` has completed execution, `inner` still has access to variables defined inside `outerFunction`.
```
### Key points:
Key points to remember:
- Closure occurs when an inner function has access to variables in its outer (lexical) scope, even when the outer function has finished executing.
- Closure allows a function to `remember` the environment in which it was created, even if that environment is no longer present.
- Closure allows a function to **remember** the environment in which it was created, even if that environment is no longer present.
- Closures are used extensively in JavaScript, such as in callbacks, event handlers, and asynchronous functions.
---
@ -40,15 +39,15 @@ closure(); // "I am from the outer function"
In JavaScript, a closure is a function that captures the lexical scope in which it was declared, allowing it to access and manipulate variables from an outer scope even after that scope has been closed.
Heres how closures work:
Here's how closures work:
1. **Lexical scoping**: JavaScript uses lexical scoping, meaning a function's access to variables is determined by its physical location within the source code.
1. **Lexical scoping**: JavaScript uses lexical scoping, meaning a function's access to variables is determined by its actual location within the source code.
1. **Function creation**: When a function is created, it keeps a reference to its lexical scope. This scope contains all the local variables that were in-scope at the time the closure was created.
1. **Maintaining state**: Closures are often used to maintain state in a secure way because the variables captured by the closure are not accessible outside the function.
## ES6 syntax and closures
With ES6, closures can be created using arrow functions, which provide a more concise syntax and lexically bind the `this` value. Heres an example:
With ES6, closures can be created using arrow functions, which provide a more concise syntax and lexically bind the `this` value. Here's an example:
```js
const createCounter = () => {
@ -64,7 +63,7 @@ console.log(counter()); // Outputs: 1
console.log(counter()); // Outputs: 2
```
### Closures in React
## Closures in React
Closures are everywhere. Below code shows a simple example of increasing a counter on a button click. In this code, `handleClick` forms a closure. It has access to it's outer scope variable `count` and `setCount`
@ -101,17 +100,18 @@ function App() {
export default App;
```
### Why use closures?
## Why use closures?
Using closures provide the following benefits:
1. **Data encapsulation**: Closures provide a way to create private variables and functions that can't be accessed from outside the closure. This is useful for hiding implementation details and maintaining state in an encapsulated way.
1. **Functional programming**: Closures are fundamental in functional programming paradigms, where they are used to create functions that can be passed around and invoked later, retaining access to the scope in which they were created, e.g. [partial applications or currying](https://medium.com/javascript-scene/curry-or-partial-application-8150044c78b8#.l4b6l1i3x).
1. **Event handlers and callbacks**: In JavaScript, closures are often used in event handlers and callbacks to maintain state or access variables that were in scope when the handler or callback was defined.
1. **Module patterns**: Closures enable the [module pattern](https://www.patterns.dev/vanilla/module-pattern) in JavaScript, allowing the creation of modules with private and public parts.
## Resources
## Further reading
- [Closures - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
- [Closures - Javascript.info](https://javascript.info/closure)
- [Closure - Eloquent Javascript](https://eloquentjavascript.net/03_functions.html)
- [You Don't Know JS Yet: Scope & Closures](https://github.com/getify/You-Dont-Know-JS/tree/2nd-ed/scope-closures)

View File

@ -92,3 +92,4 @@ console.log('End');
- [JavaScript Visualized - Event Loop, Web APIs, (Micro)task Queue by Lydia Hallie](https://www.youtube.com/watch?v=eiC58R16hb8)
- [Philip Robert's talk on the Event Loop](https://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html)
- [In The Loop by Jake Archibald](https://www.youtube.com/watch?v=cCOL7MC4Pl0).
- [JavaScript Visualized: Event Loop](https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif)

View File

@ -6,11 +6,9 @@ title: What is the definition of a higher-order function?
A higher-order function is any function that takes one or more functions as arguments, which it uses to operate on some data, and/or returns a function as a result.
Higher-order functions are meant to abstract some operation that is performed repeatedly. The classic example of this is `map`, which takes an array and a function as arguments. `map` then uses this function to transform each item in the array, returning a new array with the transformed data. Other popular examples in JavaScript are `forEach`, `filter`, and `reduce`. A higher-order function doesn't just need to be manipulating arrays as there are many use cases for returning a function from another function. `Function.prototype.bind` is one such example in JavaScript.
Higher-order functions are meant to abstract some operation that is performed repeatedly. The classic example of this is `Array.prototype.map()`, which takes an array and a function as arguments. `Array.prototype.map()` then uses this function to transform each item in the array, returning a new array with the transformed data. Other popular examples in JavaScript are `Array.prototype.forEach()`, `Array.prototype.filter()`, and `Array.prototype.reduce()`. A higher-order function doesn't just need to be manipulating arrays as there are many use cases for returning a function from another function. `Function.prototype.bind()` is an example that returns another function.
## Map
Let's say we have an array of names that we need to transform to uppercase.
Imagine a scenario where we have an array of names that we need to transform to uppercase.
```js
const names = ['irish', 'daisy', 'anna'];
@ -19,22 +17,24 @@ const names = ['irish', 'daisy', 'anna'];
The imperative way will be as such:
```js
const transformNamesToUppercase = function (names) {
function transformNamesToUppercase(names) {
const results = [];
for (let i = 0; i < names.length; i++) {
results.push(names[i].toUpperCase());
}
return results;
};
}
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
```
Use `.map(transformerFn)` makes the code shorter and more declarative.
Using `Array.prototype.map(transformerFn)` makes the code shorter and more declarative.
```js
const transformNamesToUppercase = function (names) {
function transformNamesToUppercase(names) {
return names.map((name) => name.toUpperCase());
};
}
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
```
@ -44,25 +44,27 @@ transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
A higher-order function is a function that takes another function as an argument or returns a function as its result.
### Types
### Functions as arguments
- **Function as an argument**: A function that takes another function as an argument and executes it.
A higher-order function can takes another function as an argument and execute it.
```js
function greet(name) {
return `Hello, ${name}!`;
}
function greet_name(greeter, name) {
function greetName(greeter, name) {
console.log(greeter(name));
}
greet_name(greet, 'Alice'); // Output: Hello, Alice!
greetName(greet, 'Alice'); // Output: Hello, Alice!
```
In this example, the `greet_name` function takes another function `greet` as an argument and executes it with the name `Alice`. The `greet` function is a higher-order function because it is passed as an argument to another function.
In this example, the `greetName` function takes another function `greet` as an argument and executes it with the name `Alice`. The `greet` function is a higher-order function because it is passed as an argument to another function.
- **Function as a return value**: A function that returns another function.
### Functions as return values
A higher-order function can return another function.
```js
function multiplier(factor) {
@ -80,9 +82,9 @@ console.log(triple(5)); // Output: 15
In this example, the `multiplier` function returns a new function that multiplies any number by the specified factor. The returned function is a closure that remembers the `factor` value from the outer function. The `multiplier` function is a higher-order function because it returns another function.
### Examples
### Practical examples
1. **Logging Decorator**: A higher-order function that adds logging functionality to another function:
1. **Logging decorator**: A higher-order function that adds logging functionality to another function:
```js
function withLogging(fn) {
@ -127,11 +129,27 @@ const memoizedFibonacci = memoize(fibonacci);
console.log(memoizedFibonacci(10)); // Output: 55
```
The `memoize` function is a higher-order function that takes a function `fn` as an argument and returns a new function that caches the results of the original function based on its arguments
The `memoize` function is a higher-order function that takes a function `fn` as an argument and returns a new function that caches the results of the original function based on its arguments.
## Summary
1. **Lodash**: Lodash is a utility library that provides a wide range of functions for working with arrays, objects, strings, and more, most of which are higher-order functions.
Higher-order functions can be used to create more abstract, reusable, and flexible code in JavaScript.
```js
import _ from 'lodash';
const numbers = [1, 2, 3, 4, 5];
// Filter array
const evenNumbers = _.filter(numbers, (n) => n % 2 === 0); // [2, 4]
// Map array
const doubledNumbers = _.map(numbers, (n) => n * 2); // [2, 4, 6, 8, 10]
// Find the maximum value
const maxValue = _.max(numbers); // 5
// Sum all values
const sum = _.sum(numbers); // 15
```
## Further reading

View File

@ -7,7 +7,7 @@ subtitle: What are the advantages and disadvantages to using it?
`'use strict'` is a statement used to enable strict mode to entire scripts or individual functions. Strict mode is a way to opt into a restricted variant of JavaScript.
## Advantages
**Advantages**
- Makes it impossible to accidentally create global variables.
- Makes assignments which would otherwise silently fail to throw an exception.
@ -17,7 +17,7 @@ subtitle: What are the advantages and disadvantages to using it?
- It catches some common coding bloopers, throwing exceptions.
- It disables features that are confusing or poorly thought out.
## Disadvantages
**Disadvantages**
- Many missing features that some developers might be used to.
- No more access to `function.caller` and `function.arguments`.
@ -27,13 +27,13 @@ Overall, the benefits outweigh the disadvantages and there is not really a need
---
## What is `"use strict"` in JavaScript
## What is `"use strict"` in JavaScript?
In essence, `"use strict"` is a directive introduced in ECMAScript 5 (ES5) that signals to the JavaScript engine that the code it surrounds should be executed in "strict mode". Strict mode imposes stricter parsing and error handling rules, essentially making your code more secure and less error-prone.
When you use "use strict", it helps you to write cleaner code, like preventing you from using undeclared variables. It can also make your code more secure because it disallows some potentially insecure actions.
### How to use strict mode
## How to use strict mode
1. **Global Scope**: To enable strict mode globally, add the directive at the beginning of the JavaScript file:
@ -55,34 +55,37 @@ When you use "use strict", it helps you to write cleaner code, like preventing y
}
```
### Key Features of Strict Mode
## Key features of strict mode
1. **Error Prevention** : Strict mode prevents common errors such as:
1. **Error prevention** : Strict mode prevents common errors such as:
- Using undeclared variables.
- Assigning values to non-writable properties.
- Using non-existent properties or variables.
- Deleting undeletable properties.
- Using reserved keywords as identifiers.
- Duplicating parameter names in functions.
2. **Improved Security**: Strict mode helps in writing more secure code by:
2. **Improved security**: Strict mode helps in writing more secure code by:
- Preventing the use of deprecated features like arguments.caller and arguments.callee.
- Restricting the use of eval() to prevent variable declarations in the calling scope.
3. **Compatibility** : Strict mode ensures compatibility with future versions of JavaScript by preventing the use of reserved keywords as identifiers.
### Examples
1. Preventing accidental global
1. Preventing accidental creation of global variables:
```js
// without strict mode
// Without strict mode
function defineNumber() {
count = 123;
}
defineNumber();
console.log(count); // logs: 123
```
```js
'use strict'; // With strict mode
// with strict mode
function strictFunc() {
'use strict';
strictVar = 123; // ReferenceError: strictVar is not defined
@ -94,31 +97,42 @@ When you use "use strict", it helps you to write cleaner code, like preventing y
2. Making assignments which would otherwise silently fail to throw an exception:
```js
// without strict mode
// Without strict mode
NaN = 'foo'; // This fails silently
console.log(NaN); // logs: NaN
```
// with strict mode
('use strict');
```js
'use strict'; // With strict mode
NaN = 'foo'; // TypeError: Assignment to read-only properties is not allowed in strict mode
```
3. Making attempts to delete undeletable properties throw an error in strict mode:
```js
// without strict mode
// Without strict mode
delete Object.prototype; // This fails silently
```
// with strict mode
('use strict');
```js
'use strict'; // With strict mode
delete Object.prototype; // TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
```
### Important Notes
## Is it "strictly" necessary?
1. **Placement**: The "use strict" directive must be placed at the beginning of the file or function. Placing it anywhere else will not have any effect.
2. **Compatibility**: Strict mode is supported by all modern browsers except Internet Explorer 9 and lower.
3. There is no way to cancel `"use strict"`
Adding `'use strict'` in JavaScript is still beneficial and recommended, but it is no longer strictly necessary in all cases:
1. **Modules**: The entire contents of JavaScript modules are automatically in strict mode, without needing the `'use strict'` statement. This applies to ES6 modules as well as Node.js CommonJS modules.
2. **Classes**: Code within class definitions is also automatically in strict mode, even without `'use strict'`.
While `'use strict'` is no longer mandatory in all contexts due to the automatic strict mode enforcement in modules and classes, it is still widely recommended as a best practice, especially for core JavaScript files, libraries, and when working with older browser environments or legacy code.
### Notes
1. **Placement**: The `'use strict'` directive must be placed at the beginning of the file or function. Placing it anywhere else will not have any effect.
1. **Compatibility**: Strict mode is supported by all modern browsers except Internet Explorer 9 and lower.
1. **Irreversible**: There is no way to cancel `'use strict'` after it's being set.
## Further reading

View File

@ -4,13 +4,13 @@ title: What language constructions do you use for iterating over object properti
## TL;DR
There are multiple ways to iterate over object properties as well as array in JavaScript. Following are few of them
There are multiple ways to iterate over object properties as well as array in JavaScript. The following are a few of them:
### Iterating over object properties
#### Good old `for...in` loop
The for...in loop iterates over all enumerable properties of an object, including inherited enumerable properties. So it is important to have a check if you only want to iterate over object's own properties
The `for...in` loop iterates over all enumerable properties of an object, including inherited enumerable properties. So it is important to have a check if you only want to iterate over object's own properties
```js
const obj = {
@ -29,7 +29,7 @@ for (const key in obj) {
#### Using `Object.keys()`
Object.keys() returns an array of the object's own enumerable property names. You can then use a for...of loop or forEach to iterate over this array.
`Object.keys()` returns an array of the object's own enumerable property names. You can then use a for...of loop or forEach to iterate over this array.
```js
const obj = {
@ -85,9 +85,9 @@ There are also other inbuilt methods available which are suitable for specific s
---
Iterating over object properties and array is very common in JavaScript and we have various ways to achieve this. Here are some of the ways to do it:
## Iterating over objects
## Objects
Iterating over object properties and array is very common in JavaScript and we have various ways to achieve this. Here are some of the ways to do it:
### `for...in` statement

View File

@ -1,384 +0,0 @@
---
title: What are the differences between `Map`, `Set` and `WeakMap`, `WeakSet`?
---
**TL;DR**
## `Map` vs. `Set`
### `Map`
- Collection of key-value pairs.
- Keys can be any data type.
- Maintains insertion order.
- Methods: `set`, `get`, `has`, `delete`.
- Use cases: Storing data with unique keys (e.g., configurations, caches).
```js
const map = new Map();
map.set('name', 'Alice');
map.set('age', 25);
console.log(map.get('name')); // Alice
```
### `Set`
- Collection of unique values.
- Values can be any data type.
- Maintains insertion order.
- Methods: `add`, `has`, `delete`.
- Use cases: Maintaining collections of unique values (e.g., user IDs, removing duplicates).
```js
const set = new Set();
set.add(1);
set.add(2);
set.add(1); // Duplicate ignored
console.log(set.has(1)); // true
```
## `WeakMap` vs. `WeakSet`
### `WeakMap`
- Similar to `Map`, but only allows objects as keys.
- Keys are weakly referenced (garbage-collectible).
- Not iterable, no size property.
- Use cases: Caching results, private data on third-party objects.
```js
let weakMap = new WeakMap();
let obj = { name: 'Alice' };
weakMap.set(obj, 'Developer');
obj = null; // The entry is eligible for garbage collection
```
### `WeakSet`
- Similar to `Set`, but only allows objects as values.
- Values are weakly referenced (garbage-collectible).
- Not iterable, no size property.
- Use cases: Tracking active users, detecting circular references.
```js
let weakSet = new WeakSet();
let obj1 = { name: 'Alice' };
weakSet.add(obj1);
obj1 = null; // The entry is eligible for garbage collection
```
| Feature | `Set` | `Map` | `WeakSet` | `WeakMap` |
|--------------------|----------------|----------------|-----------------------------|--------------------------|
| Key type | N/A | Any data type | N/A | Object |
| Value | Any data type | Any data type | Object | Any data type |
| Reference strength | Strong | Strong | Weak | Weak |
| Garbage collection | Not affected | Not affected | When no reference to value | When no reference to key |
---
## `Map` vs `Set`
### `Map`
A `Map` is a collection of key-value pairs where the keys can be of any data type. This is different from plain objects, where keys are typically strings or symbols.
#### Characteristics
- Keys can be any data type (primitives or objects).
- Maintains the order of insertion.
- Allows keys of any type, including objects and primitive types.
- Provides methods like `set`, `get`, `has`, and `delete`.
```js
const map = new Map();
// Setting values
map.set('name', 'Alice');
map.set('age', 25);
map.set({ city: 'New York' }, 'value can be any type');
// Getting values
console.log(map.get('name')); // Output: Alice
console.log(map.get('age')); // Output: 25
// Checking existence of a key
console.log(map.has('name')); // Output: true
// Deleting a key-value pair
map.delete('age');
// Iterating over a Map
map.forEach((value, key) => {
console.log(key, value);
});
```
#### Use cases
- Storing collections of data with unique keys, such as configurations or settings.
- Implementing caches where you need to check for the existence of keys quickly.
### `Set`
A `Set` is a collection of unique values. It ensures that no duplicates are present.
#### Characteristics
- Stores unique values of any data type (primitives like numbers, strings, or objects).
- Maintains the order of insertion.
- Only stores unique values.
- Provides methods like `add`, `has`, and `delete`.
```js
let set = new Set();
// Adding values
set.add(1);
set.add(2);
set.add(3);
set.add(1); // Duplicate values are ignored
// Checking existence of a value
console.log(set.has(1)); // Output: true
console.log(set.has(4)); // Output: false
// Deleting a value
set.delete(2);
// Iterating over a Set
set.forEach((value) => {
console.log(value);
});
```
#### Use cases
- Maintaining a collection of unique values, such as a list of user IDs or product IDs.
- Removing duplicates from an array.
## `WeakMap` vs `WeakSet`
Before undering `WeakMap` and `WeakSet`, lets first understand a bit about Garbarge collection and Weak references in JavaScript.
In JavaScript, memory management is handled by the JavaScript engine, which automatically allocates and deallocates memory as needed. Garbage collection is the process by which the engine identifies and removes objects that are no longer reachable or needed, thereby freeing up memory.
And a weak reference is a reference to an object that does not prevent the object from being garbage-collected. In JavaScript, `WeakMap` and `WeakSet` utilize weak references for their keys and values, respectively.
In `Map`, both keys and values are strongly referenced. As long as a key-value pair exists in a `Map`, both the key and value cannot be garbage-collected. And in `Set`, values are strongly referenced. As long as a value exists in a `Set`, it cannot be garbage-collected.
```js
const map = new Map();
const key = {};
map.set(key, 'value');
// Even if we set key to null, the entry in the map prevents it from being garbage collected
key = null;
// The Map still holds a reference to the original key object
console.log([...map.keys()]); // Output: [{}]
```
### `WeakMap`
A `WeakMap` is similar to a `Map`, but it only allows objects as keys and holds “weak” references to them. This means if there are no other references to the key object, it can be garbage-collected, freeing up memory.
#### Characteristics
- Keys must be objects (not primitive values).
- Holds weak references to keys.
- Not iterable and doesnt have a size property.
```js
let weakMap = new WeakMap();
let obj = { name: 'Alice' };
weakMap.set(obj, 'Developer');
// Getting values
console.log(weakMap.get(obj)); // Output: Developer
// Checking existence of a key
console.log(weakMap.has(obj)); // Output: true
// If we set obj to null, the entry in the WeakMap is eligible for garbage collection
obj = null;
// The WeakMap no longer holds a reference to the original key object
// The entry will be removed in the next garbage collection cycle
```
#### Use cases
##### Caching
A `WeakMap` can be used to store the cached results, along with the function arguments as keys. When the function is called again with the same arguments, the cached result can be retrieved from the `WeakMap`, avoiding redundant calculations.
```js
const calculationCache = new WeakMap();
function calculateExpensiveValue(obj) {
// Simulate an expensive calculation that depends on the object properties
const result = Math.random() * obj.property1 + obj.property2;
// Check if the calculation has already been done for this specific object
if (calculationCache.has(obj)) {
return calculationCache.get(obj);
}
calculationCache.set(obj, result);
return result;
}
// Usage
let myObject = { property1: 5, property2: 10 };
const result1 = calculateExpensiveValue(myObject);
const result2 = calculateExpensiveValue(myObject);
console.log(result1, result2); // Output: Will likely be the same value (cached)
// ... later, when myObject is no longer needed:
myObject = null;
// The entry in the calculationCache for myObject will be removed automatically
// when there are no other references to myObject.
```
We can use `Map` but it would be suboptimal apporach because if the reference `myObject` no longer exists, we need to clean the cache manually. Whereas, with `WeakMap`, the cached result will be removed from memory automatically after the reference object gets garbage collected.
##### Private Data on Third-Party Objects
Sometimes, you might need to associate additional data with objects that you don't own or control (e.g., objects from external libraries). Since you can't modify their prototype to add properties, a `WeakMap` can be used to store this private data, ensuring it's garbage collected when the original object is no longer needed.
```js
const libraryObject = someLibrary.createObject();
const privateData = new WeakMap();
privateData.set(libraryObject, { myCustomData: 'some value' });
// Use the private data associated with the library object
console.log(privateData.get(libraryObject).myCustomData);
```
### `WeakSet`
A `WeakSet` is similar to a Set, but it only allows objects as values and holds weak references to them.
#### Characteristics
- Only stores objects.
- Holds weak references to its values.
- Not iterable and doesnt have a size property.
```js
let weakSet = new WeakSet();
let obj1 = { name: 'Alice' };
let obj2 = { name: 'Bob' };
weakSet.add(obj1);
weakSet.add(obj2);
// Checking existence of a value
console.log(weakSet.has(obj1)); // Output: true
// Deleting a value
weakSet.delete(obj2);
// Attempting to add a primitive value throws an error
// weakSet.add(1); // TypeError: Invalid value used in weak set
```
#### Use cases
##### Tracking active users
In a chat application, you might want to track which user objects are currently active without preventing garbage collection when the user logs out or the session expires. We use a `WeakSet` to track active user objects. When a user logs out or their session expires, the user object can be garbage-collected if there are no other references to it.
```js
const activeUsers = new WeakSet();
// Function to mark a user as active
function markUserActive(user) {
activeUsers.add(user);
}
// Function to check if a user is active
function isUserActive(user) {
return activeUsers.has(user);
}
// Example usage
let user1 = { id: 1, name: 'Alice' };
let user2 = { id: 2, name: 'Bob' };
markUserActive(user1);
markUserActive(user2);
console.log(isUserActive(user1)); // true
console.log(isUserActive(user2)); // true
// Simulate user logging out
user1 = null;
// user1 is now eligible for garbage collection
console.log(isUserActive(user1)); // false
```
#### Detecting circular references
`WeakSet` is provides a way of guarding against circular data structures by tracking which objects have already been processed.
```js
// Create a WeakSet to track visited objects
const visited = new WeakSet();
// Function to traverse an object recursively
function traverse(obj) {
// Check if the object has already been visited
if (visited.has(obj)) {
return;
}
// Add the object to the visited set
visited.add(obj);
// Traverse the object's properties
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
let value = obj[prop];
if (typeof value === 'object' && value !== null) {
traverse(value);
}
}
}
// Process the object
console.log(obj);
}
// Create an object with a circular reference
const obj = {
name: 'John',
age: 30,
friends: [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 28 },
],
};
// Create a circular reference
obj.self = obj;
// Traverse the object
traverse(obj);
```
## Further reading
- [`Map` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
- [`WeakMap` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
- [`Set` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
- [`WeakSet` | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet)
- [`Map` and `Set` | Javascript.info](https://javascript.info/map-set)
- [`WeakMap` and `WeakSet` | Javascript.info](https://javascript.info/weakmap-weakset)

View File

@ -4,7 +4,14 @@ title: What's a typical use case for anonymous functions?
## TL;DR
Anonymous function in Javascript is a function that does not have any name associated with it. It is used in various scenarios to encapsulate code within a local scope, as callbacks, or as arguments to functional programming constructs.
Anonymous function in Javascript is a function that does not have any name associated with it. They are typically used as arguments to other functions or assigned to variables.
```js
// The filter method is passed an anonymous function.
arr.filter((x) => x > 1);
```
They are often used as arguments to other functions, known as higher-order functions, which can take functions as input and return a function as output. Anonymous functions can access variables from the outer scope, a concept known as closures, allowing them to "close over" and remember the environment in which they were created.
```js
// Encapsulating Code
@ -24,17 +31,20 @@ const double = arr.map(function (el) {
});
console.log(double); // [2, 4, 6]
```
---
Anonymous functions, or functions without a name, are extensively used in JavaScript for various purposes due to their flexibility and versatility.
## Anonymous functions
## Immediately Invoked Function Expressions (IIFEs)
Anonymous functions provide a more concise way to define functions, especially for simple operations or callbacks. Besides that, they can also be used in the following scenarios
Anonymous functions are commonly used in Immediately Invoked Function Expressions (IIFEs) to encapsulate code within a local scope. This prevents variables declared within the function from leaking to the global scope, and preventing namespace pollution.
### Immediate execution
Anonymous functions are commonly used in Immediately Invoked Function Expressions (IIFEs) to encapsulate code within a local scope. This prevents variables declared within the function from leaking to the global scope and polluting the global namespace.
```js
// This is an IIFE
(function() {
(function () {
var x = 10;
console.log(x); // 10
})();
@ -42,122 +52,42 @@ Anonymous functions are commonly used in Immediately Invoked Function Expression
// x is not accessible here
console.log(typeof x); // undefined
```
In the above example, the IIFE creates a local scope for the variable `x`. As a result, `x` is not accessible outside the IIFE, thus preventing it from leaking into the global scope.
## Callbacks
### Callbacks
Anonymous functions can be used as callbacks that are used once and do not need to be used anywhere else. The code will seem more self-contained and readable when handlers are defined right inside the code calling them, rather than having to search elsewhere to find the function body.
```js
setTimeout(function () {
setTimeout(() => {
console.log('Hello world!');
}, 1000);
```
## Higher-order functions
### Higher-order functions
It is used as arguments to functional programming constructs like Higher-order functions or Lodash (similar to callbacks). Higher-order functions take other functions as arguments or return them as results. Anonymous functions are often used with higher-order functions like `map()`, `filter()`, and `reduce()`.
```js
const arr = [1, 2, 3];
const double = arr.map(function (el) {
const double = arr.map((el) => {
return el * 2;
});
console.log(double); // [2, 4, 6]
```
## Additional Use Cases of Anonymous Functions as Callbacks in React
In React, anonymous functions are widely used for handling events and passing callbacks as props. Here are some common scenarios:
### Event Handling
Anonymous functions are commonly used to handle events in React components.
In React, anonymous functions are widely used for defining callback functions inline for handling events and passing callbacks as props.
```jsx
import React from 'react';
function App() {
return (
<button onClick={() => console.log('Button Clicked')}>
Click Me
</button>
);
return <button onClick={() => console.log('Clicked!')}>Click Me</button>;
}
export default App;
```
### Passing Callbacks to Child Components
Anonymous functions are often passed as props to child components to handle specific actions.
```jsx
import React from 'react';
function ChildComponent({ onButtonClick }) {
return (
<button onClick={onButtonClick}>
Click Me
</button>
);
}
function ParentComponent() {
const handleClick = () => {
console.log('Button Clicked in Parent Component');
};
return (
<ChildComponent onButtonClick={() => handleClick()} />
);
}
export default ParentComponent;
```
### Using Hooks
Anonymous functions are frequently used in conjunction with React hooks like `useState` and `useEffect`.
- `useState`:
```jsx
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
```
- `useEffect`:
```jsx
import { useEffect } from 'react';
function Timer() {
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
return () => clearInterval(timer);
}, []);
return <div>Check the console for ticks</div>;
}
export default Timer;
```
## Follow-Up Questions
- How do anonymous functions differ from named functions?
- Can you explain the difference between arrow functions and anonymous functions?
- Can you explain the difference between arrow functions and anonymous functions?

View File

@ -5,11 +5,11 @@ subtitle: How would you go about checking for any of these states?"
## TL;DR
| Characteristic | `null` | `undefined` | Undeclared |
|---------------------|-----------------------------|-----------------------------|-------------------------|
| Meaning | Explicitly set by the developer to indicate that a variable has no value | Variable has been declared but not assigned a value | Variable has not been declared at all |
| Type | `object` | `undefined` | Throws a ReferenceError |
| Equality Comparison | `null == undefined` is true | `undefined == null` is true | Throws a ReferenceError |
| Trait | `null` | `undefined` | Undeclared |
| --- | --- | --- | --- |
| Meaning | Explicitly set by the developer to indicate that a variable has no value | Variable has been declared but not assigned a value | Variable has not been declared at all |
| Type | `object` | `undefined` | Throws a `ReferenceError` |
| Equality Comparison | `null == undefined` is `true` | `undefined == null` is `true` | Throws a `ReferenceError` |
---
@ -26,40 +26,44 @@ foo();
console.log(x); // 1
```
## 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 abstract equality operator to check, as it will also return `true` if the value is `null`.
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`.
```js
var foo;
let foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === 'undefined'); // true
console.log(foo == null); // true. Wrong, don't use this to check!
console.log(foo == null); // true. Wrong, don't use this to check if a value is undefined!
function bar() {}
var baz = bar();
function bar() {} // Returns undefined if there is nothing returned.
let baz = bar();
console.log(baz); // undefined
```
## null
## `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 abstract equality operator (`==`) to check, as it will also return `true` if the value is `undefined`.
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`.
```js
var foo = null;
const foo = null;
console.log(foo === null); // true
console.log(typeof foo === 'object'); // true
console.log(foo == undefined); // true. Wrong, don't use this to check!
console.log(foo == undefined); // true. Wrong, don't use this to check if a value is null!
```
## 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 try to declare variables before using them to prevent errors
- Using some static analysis tooling in your workflow (e.g. [ESLint](https://eslint.org/), TypeScript Compiler), will usually also be able to check that you are not referencing undeclared variables.
- Always explicitly declare variables before using them to prevent errors.
- Using some static analysis tooling in your workflow (e.g. [ESLint](https://eslint.org/), TypeScript Compiler), will enable checks that you are not referencing undeclared variables.
## Practice
Practice implementing [type utilities that check for `null` and `undefined`](https://www.greatfrontend.com/questions/javascript/type-utilities?fpr=yangshun) on GreatFrontEnd.
## Further Reading

View File

@ -4,14 +4,12 @@ title: What's the difference between `.call` and `.apply`?
## TL;DR
`.call` and `.apply` are used to invoke functions with a specific this context and arguments. The primary difference lies in how they accept arguments:
`.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.
---
Both `.call` and `.apply` are used to invoke functions and the first parameter will be used as the value of `this` within the function. However, `.call` takes in comma-separated arguments as the next arguments while `.apply` takes in an array of arguments as the next argument. An easy way to remember this is C for `call` and comma-separated and A for `apply` and an array of arguments.
Assuming we have a function `add`, the function can be invoked using `.call` and `.apply` in the following manner:
```js
function add(a, b) {
@ -22,7 +20,24 @@ console.log(add.call(null, 1, 2)); // 3
console.log(add.apply(null, [1, 2])); // 3
```
With ES6 syntax, we could write the syntax of `call` using spread operator.
---
## Call vs Apply
Both `.call` and `.apply` are used to invoke functions and the first parameter will be used as the value of `this` within the function. However, `.call` takes in comma-separated arguments as the next arguments while `.apply` takes in an array of arguments as the next argument.
An easy way to remember this is C for `call` and comma-separated and A for `apply` and an array of arguments.
```js
function add(a, b) {
return a + b;
}
console.log(add.call(null, 1, 2)); // 3
console.log(add.apply(null, [1, 2])); // 3
```
With ES6 syntax, we can invoke `call` using an array along with the spread operator for the arguments.
```js
function add(a, b) {
@ -32,22 +47,11 @@ function add(a, b) {
console.log(add.call(null, ...[1, 2])); // 3
```
## Use Cases
## Use cases
### Dynamic Function Invocation
### Context management
```js
function add(a, b) {
return a + b;
}
console.log(add.call(null, 1, 2)); // 3
console.log(add.apply(null, [4, 5])); // 9
```
Both `.call` and `.apply` allow dynamic invocation of functions with specific arguments.
### Context Management
`.call` and `.apply` can set the `this` context explicitly when invoking methods on different objects.
```js
const person = {
@ -63,9 +67,9 @@ person.greet.call(anotherPerson); // Hello, my name is Alice
person.greet.apply(anotherPerson); // Hello, my name is Alice
```
`.call` and `.apply` can set the this context explicitly when invoking methods on different objects.
### Function borrowing
### Function Borrowing
Both `.call` and `.apply` allow borrowing methods from one object and using them in the context of another. This is useful when passing functions as arguments (callbacks) and the original `this` context is lost. `.call` and `.apply` allow the function to be invoked with the intended `this` value.
```js
function greet() {
@ -79,20 +83,26 @@ greet.call(person1); // Hello, my name is John
greet.call(person2); // Hello, my name is Alice
```
Both `.call` and `.apply` allow borrowing methods from one object and using them in the context of another.
### Alternative syntax to call methods on objects
### Array Manipulation
`.apply` can be used with object methods by passing the object as the first argument followed by the usual parameters.
```js
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
Array.prototype.push.apply(arr1, arr2); // Same as arr1.push(4, 5, 6)
console.log(arr1); // [1, 2, 3, 4, 5, 6]
```
`.apply` is commonly used for concatenating or manipulating arrays by passing them as arguments.
Deconstructing the above:
1. The first object, `arr1` will be used as the `this` value.
2. `.push()` is called on `arr1` using `arr2` as arguments as an array because it's using `.apply()`.
3. `Array.prototype.push.apply(arr1, arr2)` is equivalent to `arr1.push(...arr2)`.
It may not be obvious, but `Array.prototype.push.apply(arr1, arr2)` causes modifications to `arr1`. It's clearer to call methods using the OOP-centric way instead where possible.
## Follow-Up Questions
@ -100,7 +110,7 @@ console.log(arr1); // [1, 2, 3, 4, 5, 6]
## Practice
- Try implementing your own [`Function.prototype.call` method](/questions/javascript/function-call) and [`Function.prototype.apply` method](/questions/javascript/function-apply) on GreatFrontEnd.
Practice implementing your own [`Function.prototype.call` method](/questions/javascript/function-call) and [`Function.prototype.apply` method](/questions/javascript/function-apply) on GreatFrontEnd.
## Further Reading

View File

@ -4,12 +4,14 @@ title: Why is extending built-in JavaScript objects not a good idea?
## TL;DR
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.
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 have unpredictable behavior if these two methods do not work the same way.
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.
---
## Extending JavaScript
In JavaScript it's very easy to extend a built-in/native object. You can simply extend a built-in object by adding properties and functions to its `prototype`.
```js
@ -19,7 +21,7 @@ String.prototype.reverseString = function () {
console.log('hello world'.reverseString()); // Outputs 'dlrow olleh'
// instead of extending the built in object you can write a simple utility function to do it
// Instead of extending the built-in object, write a pure utility function to do it.
function reverseString(str) {
return str.split('').reverse().join('');
@ -28,28 +30,40 @@ function reverseString(str) {
console.log(reverseString('hello world')); // Outputs 'dlrow olleh'
```
### Disadvantages
## Disadvantages
It is not recommended to extend built-in objects. Extending built-in JavaScript objects can have several disadvantages:
Extending built-in JavaScript objects is essentially modifying the global scope and it's not a good idea because:
1. **Future Proofing**: If a browser decides to implement its own version of a method, your custom extension might get overridden silently, leading to unexpected behavior or conflicts.
1. **Future-proofing**: If a browser decides to implement its own version of a method, your custom extension might get overridden silently, leading to unexpected behavior or conflicts.
2. **Collisions**: Adding custom methods to built-in objects can lead to collisions with future browser implementations or other libraries, causing unexpected behavior or errors.
3. **Maintenance and Debugging**: When extending built-in objects, it can be difficult for other developers to understand the changes made, making maintenance and debugging more challenging.
3. **Maintenance and debugging**: When extending built-in objects, it can be difficult for other developers to understand the changes made, making maintenance and debugging more challenging.
4. **Performance**: Extending built-in objects can potentially impact performance, especially if the extensions are not optimized for the specific use case.
5. **Security**: In some cases, extending built-in objects can introduce security vulnerabilities if not done correctly, such as adding enumerable properties that can be exploited by malicious code.
6. **Compatibility**: Custom extensions to built-in objects may not be compatible with all browsers or environments, leading to issues with cross-browser compatibility.
7. **Namespace Clashes**: Extending built-in objects can lead to namespace clashes if multiple libraries or scripts extend the same object in different ways, causing conflicts and unexpected behavior.
7. **Namespace clashes**: Extending built-in objects can lead to namespace clashes if multiple libraries or scripts extend the same object in different ways, causing conflicts and unexpected behavior.
### Alternatives to extending built-in objects:
We dive deeper into [why it is a bad idea to modify the global scope](/questions/quiz/why-is-it-in-general-a-good-idea-to-leave-the-global-scope-of-a-website-as-is-and-never-touch-it).
It is not recommended to extend built-in objects due to these potential issues and instead suggest using composition or creating custom classes and utility functions to achieve the desired functionality.
## Alternatives to extending built-in objects
Instead of extending built-in objects, do the following instead:
1. **Create custom utility functions**: For simple tasks, creating small utility functions specific to your needs can be a cleaner and more maintainable solution.
2. **Use libraries and frameworks**: Many libraries and frameworks provide their own helper methods and extensions, eliminating the need to modify built-in objects directly.
## Summary
## Polyfilling as a valid reason
Many developers and experts recommend against extending built-in objects due to these potential issues and instead suggest using composition or creating custom classes and utility functions to achieve the desired functionality.
One valid reason to extend built-in objects is to implement polyfills for the latest ECMAScript standard and proposals. [`core-js`](https://github.com/zloirock/core-js) is a popular library that is present on most popular websites. It not only polyfills missing features but also fixes incorrect or non-compliant implementations of JavaScript features in various browsers and runtimes.
```js
import 'core-js/actual/array/flat-map'; // With this, Array.prototype.flatMap is available to be used.
[1, 2].flatMap((it) => [it, it]); // => [1, 1, 2, 2]
```
## Further reading
- [JS: dont extend JS objects](https://lucybain.com/blog/2014/js-extending-built-in-objects/)
- [JS: don't extend JS objects](https://lucybain.com/blog/2014/js-extending-built-in-objects/)
- [Extending built-in classes](https://javascript.info/extend-natives)

View File

@ -4,13 +4,58 @@ title: Why is it, in general, a good idea to leave the global scope of a website
## TL;DR
JavaScript that is executed in the browser has access to the global scope, and if everyone uses the global namespace to define their variables, collisions will likely occur. Use the module pattern (IIFEs) to encapsulate your variables within a local namespace.
JavaScript that is executed in the browser has access to the global scope (the `window` object). In general it's a good software engineering practice to not pollute the global namespace unless you are working on a feature that truly needs to be global it is needed by the entire page. Several reasons to avoid touching the global scope:
### Example
- **Naming conflicts**: Sharing the global scope across scripts can cause conflicts and bugs when new global variables or changes are introduced.
- **Cluttered global namespace**: Keeping the global namespace minimal avoids making the codebase hard to manage and maintain.
- **Scope leaks**: Unintentional references to global variables in closures or event handlers can cause memory leaks and performance issues.
- **Modularity and encapsulation**: Good design promotes keeping variables and functions within their specific scopes, enhancing organization, reusability, and maintainability.
- **Security concerns**: Global variables are accessible by all scripts, including potentially malicious ones, posing security risks, especially if sensitive data is stored there.
- **Compatibility and portability**: Heavy reliance on global variables reduces code portability and integration ease with other libraries or frameworks.
#### Using global scope
Follow these best practices to avoid global scope pollution:
- **Use local variables**: Declare variables within functions or blocks using `var`, `let`, or `const` to limit their scope.
- **Pass variables as function parameters**: Maintain encapsulation by passing variables as parameters instead of accessing them globally.
- **Use immediately invoked function expressions (IIFE)**: Create new scopes with IIFEs to prevent adding variables to the global scope.
- **Use modules**: Encapsulate code with module systems to maintain separate scopes and manageability.
---
## What is the global scope?
In the browser, the global scope is the top-level context where variables, functions, and objects are accessible from anywhere in the code. The global scope is represented by the `window` object. Any variables or functions declared outside of any function or block (that is not within any module) are added to the `window` object and can be accessed globally.
For example:
```js
// Assuming this is run in the global scope and not within a module.
const globalVariable = 'I am global';
function globalFunction() {
console.log('I am a global function');
}
console.log(window.globalVariable); // 'I am global'
window.globalFunction(); // 'I am a global function'
```
In this example, `globalVariable` and `globalFunction` are added to the `window` object and can be accessed from anywhere in the global context.
## Pitfalls of global scope
In general, it's a good software engineering practice to not pollute the global namespace unless you are working on a feature that truly needs to be global it is needed by the entire page. There are many reasons to avoid touching the global scope:
- **Naming conflicts**: The global scope is shared across all scripts on a web page. If you introduce new global variables or modify existing ones, you risk causing naming conflicts with other scripts or libraries used on the same page. This can lead to unexpected behavior and difficult-to-debug issues.
- **Cluttered global namespace**: The global namespace should be kept as clean and minimal as possible. Adding unnecessary global variables or functions can clutter the namespace and make it harder to manage and maintain the codebase over time.
- **Scope leaks**: When working with closures or event handlers, it's easy to accidentally create unintended references to global variables, leading to memory leaks and performance issues. By avoiding global variables altogether, you can prevent these types of scope leaks.
- **Modularity and encapsulation**: One of the principles of good software design is modularity and encapsulation. By keeping variables and functions within their respective scopes (e.g., module, function, or block scope), you promote better code organization, reusability, and maintainability.
- **Security concerns**: Global variables can be accessed and modified by any script running on the page, including potentially malicious scripts. It is quite common for websites to load third-party scripts and in the event someone's network is compromised, it can pose security risks, especially if sensitive data is stored in global variables. However, in the first place you should not expose any sensitive data on the client.
- **Compatibility and portability**: By relying heavily on global variables, your code becomes less portable and more dependent on the specific environment it was written for. This can make it harder to integrate with other libraries or frameworks, or to run the code in different environments (e.g., server-side vs browser).
Here's an example of global scope being used.
```js
// Assuming this is run in the global scope, not within a module.
let count = 0;
function incrementCount() {
@ -27,11 +72,19 @@ incrementCount(); // Output: 1
decrementCount(); // Output: 0
```
In this example, `count`, `incrementCount`, and `decrementCount` are all defined in the global scope. Any script on the page can access and modify these variables and functions.
In this example, `count`, `incrementCount`, and `decrementCount` are defined on the global scope. Any script on the page can access and modify the `count`, as well as all variables on `window`.
#### Using IIFE (Immediately invoked function expression)
## Avoiding global scope pollution
By now we hope that you're convinced that it's not a good idea to define variables on the global scope. To avoid polluting the global scope, it is recommended to follow best practices such as:
- **Use local variables**: Declare variables within functions or blocks to limit their scope and prevent them from being accessed globally. Use `var`, `let`, or `const` to declare variables within a specific scope, ensuring they are not accidentally made global.
- **Pass variables as function parameters:**: Instead of accessing variables directly from the outer scope, pass them as parameters to functions to maintain encapsulation and avoid global scope pollution.
- **Use modules**: Utilize module systems to encapsulate your code and prevent global scope pollution. Each module has its own scope, making it easier to manage and maintain your code.
- **Use immediately invoked function expressions (IIFE)**: If modules are not available, wrap your code in an IIFE to create a new scope, preventing variables from being added to the global scope unless you explicitly expose them.
```js
// Assuming this is run in the global scope, not within a module.
(function () {
let count = 0;
@ -50,36 +103,13 @@ incrementCount(); // Output: 1
decrementCount(); // Output: 0
```
In this example, `count` is not accessible in the global scope. It can only be accessed and modified by the `incrementCount` and `decrementCount` functions. These functions are exposed to the global scope by attaching them to the `window` object, but they still have access to the `count` variable in their parent scope. This provides a way to encapsulate data and avoid polluting the global scope.
In this example, `count` is not accessible in the global scope. It can only be accessed and modified by the `incrementCount` and `decrementCount` functions. These functions are exposed to the global scope by attaching them to the `window` object, but they still have access to the `count` variable in their parent scope. This provides a way to encapsulate the underlying data and only expose the necessary operations no direct manipulation of the value is allowed.
---
In JavaScript, it is very easy to define variables and functions in global scope. You can declare a variable globally by simply assigning a value to it outside of any function:
```js
var myGlobalVar = 'Hello World';
```
Global variables are accessible from anywhere in your JavaScript code. It's generally recommended to avoid using global variables whenever possible due to following reasons:
1. **Global Variables are Considered a "Bad Thing"**: Global variables are generally considered a bad practice in most programming languages, including JavaScript. They can lead to code that is harder to read, maintain, and debug.
2. **Unpredictable Behavior**: Global variables can be updated from any point in the program, making it difficult to predict their values. This can lead to unexpected behavior and side effects.
3. **Name Clashes**: Since there is only one global namespace, it is more likely to encounter name clashes with other variables or libraries. This can cause conflicts and errors.
4. **Performance and Implementation Complexity**: The global object in JavaScript can negatively impact performance and make the implementation of variable scoping more complicated.
5. **Less Modular Code**: Global variables can lead to less modular code, making it harder to reuse and maintain different parts of the program independently
### How to avoid global scope pollution
To avoid polluting the global scope in JavaScript, consider the following strategies:
1. **Use local variables**: Declare variables within functions or blocks to limit their scope and prevent them from being accessed globally. Use var, let, or const to declare variables within a specific scope, ensuring they are not accidentally made global
2. **Pass variables as function parameters:**: Instead of accessing variables directly from the outer scope, pass them as parameters to functions to maintain encapsulation and avoid global scope pollution.
3. **Use immediately invoked function expressions (IIFE)**: Wrap your code in an IIFE to create a new scope, preventing variables from being added to the global scope unless you explicitly expose them.
4. **Use modules**: Utilize module systems to encapsulate your code and prevent global scope pollution. Each module has its own scope, making it easier to manage and maintain your code.
## Further reading
- [JS: dont touch the global scope](https://lucybain.com/blog/2014/js-dont-touch-global-scope/)
- [Variables: Scopes, Environments, and Closures](https://exploringjs.com/es5/ch16.html)
- [JavaScript modules - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
- [Modules, introduction](https://javascript.info/modules-intro)
- [JS: don't touch the global scope](https://lucybain.com/blog/2014/js-dont-touch-global-scope/)
- [Variables: Scopes, Environments, and Closures](https://exploringjs.com/es5/ch16.html)

View File

@ -1,33 +1,43 @@
---
title: Why you might want to create static class members?
title: Why might you want to create static class members?
---
## TL;DR
Static class members (properties/methods) has a static keyword prepended to itself. Such members cannot be directly accessed on instances of the class. Instead, they're accessed on the class itself.
Static class members (properties/methods) has a `static` keyword prepended. Such members cannot be directly accessed on instances of the class. Instead, they're accessed on the class itself.
```js
class Car {
static noOfWheel = 4;
static noOfWheels = 4;
static compare() {
return 'static method has been called.';
return 'Static method has been called.';
}
}
console.log(Car.noOfWheels); // 4
```
Static members are useful under the following scenarios:
- **Namespace organization**: Static properties can be used to define constants or configuration values that are specific to a class. This helps organize related data within the class namespace and prevents naming conflicts with other variables. Examples include `Math.PI`, `Math.SQRT2`.
- **Helper functions**: Static methods can be used as helper functions that operate on the class itself or its instances. This can improve code readability and maintainability by separating utility logic from the core functionality of the class. Examples of frequently used static methods include `Object.assign()`, `Math.max()`.
- **Singleton pattern**: In some rare cases, static properties and methods can be used to implement a singleton pattern, where only one instance of a class ever exists. However, this pattern can be tricky to manage and is generally discouraged in favor of more modern dependency injection techniques.
---
Static class members (properties/methods) are not tied to a specific instance of a class and have the same value regardless of which instance is referring to it. Static properties are typically configuration variables and static methods are usually pure utility functions which do not depend on the state of the instance. Such properties has a static keyword prepended to itself.
## Static class members
Static class members (properties/methods) are not tied to a specific instance of a class and have the same value regardless of which instance is referring to it. Static properties are typically configuration variables and static methods are usually pure utility functions which do not depend on the state of the instance. Such properties has a `static` keyword prepended.
```js
class Car {
static noOfWheel = 4;
static noOfWheels = 4;
static compare() {
return 'static method has been called.';
}
}
console.log(Car.noOfWheel); // Output: 4
console.log(Car.noOfWheels); // Output: 4
console.log(Car.compare()); // Output: static method has been called.
```
@ -35,14 +45,14 @@ Static members are not accessible by specific instance of class.
```js
class Car {
static noOfWheel = 4;
static noOfWheels = 4;
static compare() {
return 'static method has been called.';
}
}
const car = new Car();
console.log(car.noOfWheel); // Output: undefined
console.log(car.noOfWheels); // Output: undefined
console.log(car.compare()); // Error: TypeError: car.compare is not a function
```
@ -54,27 +64,26 @@ console.log(Math.abs(-5)); // Output: 5
console.log(Math.max(1, 2, 3)); // Output: 3
```
In this example, `PI`, `abs()`, and `max()` are all static members of the `Math` class. They can be accessed directly on the `Math` object without the need to create an instance of the class.
In this example, `Math.PI`, `Math.abs()`, and `Math.max()` are all static members of the `Math` class. They can be accessed directly on the `Math` object without the need to create an instance of the class.
## Reasons to Use Static Class Members
## Reasons to use static class members
### Utility Functions
### Utility functions
Static class members can be useful for defining utility functions that don't require any instance-specific data or behavior. For example, you might have a Math class with static methods for common mathematical operations.
Static class members can be useful for defining utility functions that don't require any instance-specific (don't use `this`) data or behavior. For example, you might have a `Arithmetic` class with static methods for common mathematical operations.
```js
class Math {
class Arithmetic {
static add(a, b) {
return a + b;
}
static subtract(a, b) {
return a - b;
}
}
console.log(Math.add(2, 3)); // Output: 5
console.log(Math.subtract(5, 2)); // Output: 3
console.log(Arithmetic.add(2, 3)); // Output: 5
console.log(Arithmetic.subtract(5, 2)); // Output: 3
```
### Singletons

View File

@ -14,7 +14,7 @@ module.exports = {
themeConfig: {
announcementBar: {
id: 'gfe', // Increment on change
content: `⭐️ We are now part of <a href="https://www.greatfrontend.com/?utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=banner&fpr=frontendinterviewhandbook" target="_blank">GreatFrontEnd</a>, a front end interview preparation platform created by ex-FAANG Senior Engineers. <a href="https://www.greatfrontend.com/?utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=banner&fpr=frontendinterviewhandbook" target="_blank">Get 20% off today</a>! ⭐️`,
content: `⭐️ We are now part of <a href="https://www.greatfrontend.com/?fpr=yangshun&utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=banner&fpr=frontendinterviewhandbook" target="_blank">GreatFrontEnd</a>, a front end interview preparation platform created by ex-FAANG Senior Engineers. <a href="https://www.greatfrontend.com/?fpr=yangshun&utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=banner&fpr=frontendinterviewhandbook" target="_blank">Get 20% off today</a>! ⭐️`,
isCloseable: false,
},
prism: {
@ -36,15 +36,15 @@ module.exports = {
items: [
{
label: 'Coding Questions',
href: 'https://www.greatfrontend.com/prepare/coding',
href: 'https://www.greatfrontend.com/prepare/coding?fpr=yangshun',
},
{
label: 'System Design',
href: 'https://www.greatfrontend.com/prepare/system-design',
href: 'https://www.greatfrontend.com/prepare/system-design?fpr=yangshun',
},
{
label: 'Quiz Questions',
href: 'https://www.greatfrontend.com/prepare/quiz',
href: 'https://www.greatfrontend.com/prepare/quiz?fpr=yangshun',
},
],
},
@ -154,7 +154,7 @@ module.exports = {
items: [
{
label: 'GreatFrontEnd',
href: 'https://www.greatfrontend.com',
href: 'https://www.greatfrontend.com?fpr=yangshun',
},
{
label: 'GitHub',

View File

@ -34,7 +34,7 @@ function GreatFrontEnd({ position }) {
return (
<a
className={clsx(styles.container, styles.backgroundPurple)}
href={`https://www.greatfrontend.com?utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=${position}&fpr=frontendinterviewhandbook`}
href={`https://www.greatfrontend.com?fpr=yangshun&utm_source=frontendinterviewhandbook&utm_medium=referral&utm_content=${position}&fpr=frontendinterviewhandbook`}
target="_blank"
rel="noopener"
onClick={() => {

View File

@ -101,7 +101,7 @@ function GreatFrontEndSection() {
<div className="margin-vert--md">
<a
className="button button--secondary button--lg"
href="https://www.greatfrontend.com/prepare/"
href="https://www.greatfrontend.com/prepare?fpr=yangshun"
rel="noopener"
target="_blank"
onClick={() => {