JavaScript can be pretty confusing. It's pass-by-value, but what does that even mean? So, let's dive in. In a nutshell: everything in JavaScript is passed by value - it's that simple. But, the type of data you're working with changes everything. Primitives, like numbers or strings, are passed by value - no surprises there. Objects, on the other hand, are passed by value too, but the value is a reference to the object, which is where things get tricky. When you pass a primitive, JavaScript makes a copy of the data, and the original and the copy are independent - easy peasy. But with objects, it's like sharing a secret: if you change the object, everyone who has a reference to it sees the change. You can use the spread operator or structuredClone() to create copies of objects, but be careful - objects and arrays can share references, which can lead to some weird behavior. It's like trying to have a conversation in a crowded room: you think you're talking to one person, but really, everyone is listening. So, to write clean code, use immutability - never change the original data, just return a new version. It's like taking a snapshot: you capture the moment, and then you can move on. And, yeah, it's worth repeating: JavaScript is always pass-by-value. Primitives are safe from external changes, but objects and arrays share references, so be careful. Use the spread operator or structuredClone() to create copies, and always, always embrace immutability for predictable code. Check out this article for more info: https://lnkd.in/g-Nj9Rh6 #JavaScript #Immutability #CleanCode #PassByValue #ProgrammingBestPractices
JavaScript Pass-by-Value: Understanding Primitives and Objects
More Relevant Posts
-
JavaScript Hoisting: The Concept That Separates “I use JS” from “I understand JS” Hoisting is one of those JavaScript behaviors that silently explains why some code works, and why some bugs are so hard to catch. In JavaScript, code runs in two phases: 1️⃣ Compilation (creation) phase 2️⃣ Execution phase During compilation, JavaScript sets up memory for variables and functions. This is where hoisting happens. 🔹 var hoisting Only the declaration is hoisted, not the initialization. ex: console.log(x); // undefined var x = 5; Behind the scenes, JavaScript treats it like: var x; console.log(x); x = 5; No error, but also no value yet. This behavior has caused countless subtle bugs in real-world apps. 🔹 Function declarations Function declarations are fully hoisted, name and body. sayHello(); // works function sayHello() { console.log("Hello"); } This is why function declarations behave differently from function expressions. 🔹 let & const (ES6) They are hoisted, but not initialized. Accessing them before declaration throws a ReferenceError. console.log(y); // ReferenceError let y = 10; This period is known as the Temporal Dead Zone (TDZ), a design choice to make code safer and more predictable. 💡 Why this matters in real projects - Explains unexpected undefined - Helps debug scope-related issues - Shows you understand how JS actually works under the hood 📌 Best practice Don’t rely on hoisting. Write code that’s clear, intentional, and predictable, your future self (and your team) will thank you. #JavaScript #Frontend #WebDevelopment #SoftwareEngineering #CleanCode
To view or add a comment, sign in
-
𝗠𝗶𝗰𝗿𝗼𝘁𝗮𝗸𝘀 𝗮𝗻𝗱 𝗠𝗮𝗰𝗿𝗼𝘁𝗮𝗸𝘀: 𝗘𝘃𝗲𝗻𝘁 𝗟𝗼𝗼𝗽 𝗗𝗲𝗺𝘆𝘀𝘁𝗶𝗳𝗶𝗲𝗱 You need to understand how JavaScript's event loop works. It helps you manage tasks and events in a non-blocking way. This is crucial for senior developers working on complex web applications. When a JavaScript program runs, it goes through a series of tasks. These tasks can be user interactions, network requests, timers, or promises. There are two types of tasks: macrotasks and microtasks. - Macrotasks include: - setTimeout - setInterval - I/O operations - Microtasks include: - Promise callbacks - Mutation Observers The event loop executes these tasks in a specific order. It runs a macrotask, then all the microtasks queued during that macrotask, until the microtask queue is empty. This means microtasks can interrupt macrotasks. Here's an example: ```javascript console.log('Start'); setTimeout(() => { console.log('Macrotask 1 completed'); }, 0); Promise.resolve().then(() => { console.log('Microtask 1 completed'); }); setTimeout(() => { console.log('Macrotask 2 completed'); }, 0); Promise.resolve().then(() => { console.log('Microtask 2 completed'); }); console.log('End'); ``` The output will be: ``` Start End Microtask 1 completed Microtask 2 completed Macrotask 1 completed Macrotask 2 completed ``` This shows that microtasks are completed before macrotasks. Understanding microtasks and macrotasks is vital for writing reliable and performant code. You can use them to ensure critical code executes immediately after the current task finishes. However, overusing microtasks can introduce performance issues. To optimize performance, ensure heavy computations or rendering logic reside within macrotasks. Use debouncing and throttling strategies for repetitive async calls. For further learning, check out: MDN Web Docs on Promises HTML Living Standard: The Event Loop JavaScript: The Definitive Guide Source: https://lnkd.in/gk_rM4Ur
To view or add a comment, sign in
-
𝗠𝗶𝗰𝗿𝗼𝘁𝗮𝗸𝘀 𝗮𝗻𝗱 𝗠𝗮𝗰𝗿𝗼𝘁𝗮𝗸𝘀: 𝗘𝘃𝗲𝗻𝘁 𝗟𝗼𝗼𝗽 𝗗𝗲𝗺𝘆𝘀𝘁𝗶𝗳𝗶𝗲𝗱 You need to understand how JavaScript's event loop works. It helps you manage tasks and events in a non-blocking way. This is crucial for senior developers working on complex web applications. When a JavaScript program runs, it goes through a series of tasks. These tasks can be user interactions, network requests, timers, or promises. There are two types of tasks: macrotasks and microtasks. - Macrotasks include: - setTimeout - setInterval - I/O operations - Microtasks include: - Promise callbacks - Mutation Observers The event loop executes these tasks in a specific order. It runs a macrotask, then all the microtasks queued during that macrotask, until the microtask queue is empty. This means microtasks can interrupt macrotasks. Here's an example: ```javascript console.log('Start'); setTimeout(() => { console.log('Macrotask 1 completed'); }, 0); Promise.resolve().then(() => { console.log('Microtask 1 completed'); }); setTimeout(() => { console.log('Macrotask 2 completed'); }, 0); Promise.resolve().then(() => { console.log('Microtask 2 completed'); }); console.log('End'); ``` The output will be: ``` Start End Microtask 1 completed Microtask 2 completed Macrotask 1 completed Macrotask 2 completed ``` This shows that microtasks are completed before macrotasks. Understanding microtasks and macrotasks is vital for writing reliable and performant code. You can use them to ensure critical code executes immediately after the current task finishes. However, overusing microtasks can introduce performance issues. To optimize performance, ensure heavy computations reside within macrotasks. Use debouncing and throttling strategies for repetitive async calls. For further learning, check out: MDN Web Docs on Promises HTML Living Standard: The Event Loop JavaScript: The Definitive Guide Source: https://lnkd.in/gk_rM4Ur
To view or add a comment, sign in
-
Stop using `new CustomEvent()`. There is a much better way to handle events in JavaScript. 1. The old habit For years, we have used `CustomEvent` to pass data around. It works, but it has flaws. You have to wrap your data inside a detail property. It feels clunky and "unnatural" compared to other objects. 2. The problem with CustomEvent It creates friction in your code: - The syntax is verbose. - You cannot access your data directly (you always need .detail). - It is difficult to type correctly in TypeScript. 3. The modern solution You don't need `CustomEvent` anymore. You can simply create your own class and extend `Event`. It looks like this: class UserLoginEvent extends Event { ... } 4. Why is it better? Subclassing `Event` is the standard way now. It offers clear advantages: - It uses standard JavaScript class syntax. - Your data sits on the event itself, not inside .detail. - It is much easier to define types for your custom events. - It works in all modern browsers. 5. It is time to upgrade If you want cleaner, strictly typed events, try extending the native `Event` class. It makes your code easier to read and maintain. Do you still use `CustomEvent` or have you switched?
To view or add a comment, sign in
-
-
One line of JavaScript can replace an entire if/else block. The ternary operator might be the “question” that your code needs. The formally named “Conditional (ternary) operator” goes by many common names including: a ternary, one-line conditional, and shorthand if/else. It’s a powerful bit of JavaScript that can help you cut down on some of your if statements. A ternary’s syntax is structured sort of like a question: condition ? valueIfTruthy : valueIfFalsy The condition is an expression whose value will come in as either truthy or falsy - no those aren’t typos. Truthy and falsy are values that when considered in a boolean context come back as true or false, respectively. All values are truthy except for: false, 0, -0, 0n, null, undefined, NaN, and document.all. Let’s take this syntax and apply it to a practice example, checking if the user is a Prime member. const isPrimeMember = true; const shippingTime = isPrimeMember ? "2 Days" : "7 Days"; // shippingTime = 2 Days If we didn’t use a ternary, our code might look something like this: const isPrimeMember = true; if (isPrimeMember) { shippingTime = "2 Days"; } else { shippingTime = "7 Days"; } This code is totally valid, but you can see that by using a ternary we’ve used 2 lines rather than 7. Once you get comfortable with ternaries, you’ll start spotting places where they make your code cleaner and easier to read. They show up everywhere - especially in React - so getting familiar with them early pays off fast.
To view or add a comment, sign in
-
-
Understanding why Promise.all() needs an array in JavaScript Many developers try this and get confused 👇 ❌ Wrong way Promise.all(p1, p2); ✅ Correct way Promise.all([p1, p2]); 🤔 Why does this happen? Promise.all() accepts only ONE argument, and that argument must be an iterable (most commonly an array). 👉 An array allows JavaScript to loop through multiple promises and wait for all of them to resolve. ✅ Working example let p1 = new Promise((resolve) => { resolve(1); }); let p2 = new Promise((resolve) => { resolve(2); }); Promise.all([p1, p2]) .then((data) => { console.log(data); // [1, 2] }); ❌ Why `Promise.all(p1, p2)` throws an error? When you write: Promise.all(p1, p2); JavaScript treats it as: Promise.all(p1); But p1 is a "Promise object", not an iterable like an array. So JS throws: TypeError: object is not iterable 🧠 Easy way to remember > Promise.all waits for a collection of promises, not individual ones Always wrap promises inside an array. ⚠️ One more important thing If any promise rejects, Promise.all() immediately rejects. Promise.all([Promise.resolve(1), Promise.reject("Error")]) .catch(console.error); // Error 💡 Hope this helps someone avoid a common JavaScript pitfall! . . . . . #SRYTAL #JavaScript #Promises #WebDevelopment #Frontend #Learning #Promise.all #Growtogether
To view or add a comment, sign in
-
🤔 Quick question: When JavaScript runs async code, where does everything actually go? After learning about the Call Stack and Event Loop, I realized something important: JavaScript doesn’t work alone — it collaborates with Web APIs and queues 👇 --------------------------- console.log("Start"); setTimeout(() => { console.log("Timeout"); }, 0); console.log("End"); ---------------------------- Output: - Start - End - Timeout 💡 What happens behind the scenes? - console.log("Start") → pushed to the Call Stack - setTimeout → handed off to Web APIs - console.log("End") → runs immediately Once the Call Stack is empty: - Event Loop checks the Task Queue - setTimeout callback is pushed back to the stack - Callback executes How the pieces fit together Call Stack → executes JavaScript Web APIs → handle timers, DOM events, network calls Queues → hold callbacks waiting to run Event Loop → coordinates everything Takeaway JavaScript executes code using the Call Stack, offloads async work to Web APIs, and uses the Event Loop to decide when callbacks can run. #JavaScript #WebDevelopment #FullStack #LearningInPublic
To view or add a comment, sign in
-
Understanding why `Promise.all()` needs an array in JavaScript Many developers try this and get confused 👇 ❌ Wrong way Promise.all(p1, p2); ✅ Correct way Promise.all([p1, p2]); 🤔 Why does this happen? Promise.all() accepts only ONE argument, and that argument must be an iterable (most commonly an array). 👉 An array allows JavaScript to loop through multiple promises and wait for all of them to resolve. ✅ Working example let p1 = new Promise((resolve) => { resolve(1); }); let p2 = new Promise((resolve) => { resolve(2); }); Promise.all([p1, p2]) .then((data) => { console.log(data); // [1, 2] }); ❌ Why `Promise.all(p1, p2)` throws an error? When you write: Promise.all(p1, p2); JavaScript treats it as: Promise.all(p1); But p1 is a "Promise object", not an iterable like an array. So JS throws: TypeError: object is not iterable 🧠 Easy way to remember > Promise.all waits for a collection of promises, not individual ones Always wrap promises inside an array. ⚠️ One more important thing If any promise rejects, Promise.all() immediately rejects. Promise.all([Promise.resolve(1), Promise.reject("Error")]) .catch(console.error); // Error 💡 Hope this helps someone avoid a common JavaScript pitfall! . . . . . #SRYTAL #JavaScript #Promises #WebDevelopment #Frontend #Learning #Promise.all #Growtogether
To view or add a comment, sign in
-
JavaScript usually feels fine until the same function suddenly behaves differently, and nothing makes sense. 👀 The code looks identical, nothing was touched, and yet the result changed. Frustration usually shows up right there. Not because of broken logic, but because 'this' isn't what it looked like. 🎭 And that's the tricky part. It's not a syntax problem; it's about execution context. In JavaScript, 'this' isn't locked in when the function is written. Its value is determined when the function runs. Change how it's called, and the behavior shifts with it. Same code, different call. Once that clicks, those "why is this undefined?" moments stop feeling random. They start feeling predictable. 🧠 The confusion fades because there's finally a mental model behind it. So here's the question worth pausing on: When exactly does JavaScript decide what 'this' points to? This is where it starts to feel obvious: https://lnkd.in/dWpngz9z
To view or add a comment, sign in
-
𝗝𝗮 v𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗘 v𝗲𝗻𝘁 𝗟𝗼𝗼𝗽 𝗘𝘅𝗽𝗹𝗮𝗶𝗻𝗲𝗱 You write JavaScript code and it runs out of order. This happens because of the JavaScript event loop. Understanding the event loop helps you write faster and bug-free applications. JavaScript is single-threaded. It executes one piece of code at a time. But it handles asynchronous operations like HTTP requests and timers. The event loop is a queue manager. It keeps track of tasks and executes them in the right order. There are two main types of task queues: - Macrotasks: examples are setTimeout and I/O events - Microtasks: examples are Promise.then() and process.nextTick Microtasks have higher priority than macrotasks. This is why promises run before setTimeout callbacks. For example: - You start a task - setTimeout is queued as a macrotask - A promise is queued as a microtask - The microtask queue runs the promise - The macrotask queue runs the timeout Async functions are syntactic sugar over promises. They pause execution and schedule the continuation as a microtask. High-scale applications like Exact Solution Marketplace use the event loop to handle thousands of concurrent requests. They manage microtasks and macrotasks to maintain fast response times. To avoid pitfalls: - Avoid blocking the main thread - Don't ignore microtask queue effects - Don't misuse setTimeout for async logic - Watch out for memory leaks Understanding the event loop is critical for building high-performance apps. You can avoid subtle bugs and improve performance. Source: https://lnkd.in/gRvBS9b5
To view or add a comment, sign in
Explore related topics
- How to Write Clean, Collaborative Code
- How to Write Maintainable, Shareable Code
- How to Improve Code Maintainability and Avoid Spaghetti Code
- How to Modify Existing Code Confidently
- How to Ensure Cohesive Code Samples
- How To Handle Legacy Code Cleanly
- Transitioning to Disposable Code Design Practices
- Salesforce Object Best Practices for Preventing Code Entanglement
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development