جاوااسکریپت | JavaScript
507 subscribers
654 photos
139 videos
3 files
512 links
کانال @IR_javascript حاوی اطلاعات مفید در حوزه برنامه نویس فرانت که بصورت روزانه بروز می‌شود.
در این کانال شما به:
[1] مطالب تازه
[2] تحلیل‌های عمیق
[3] نکات آموزشی
[4] چالش
[5] ابزار و راهنمایی‌های کاربردی
دسترسی خواهید داشت.

🆔@IR_javascript
Download Telegram
### انواع رشته‌ای قالب‌دار (Template Literal Types) در TypeScript: چرا به آن‌ها نیاز داریم؟ 🤨

با آن‌که این قابلیت‌ها به‌طور مکرر استفاده نمی‌شوند، اما می‌توانند حل برخی مسائل خاص را بسیار ساده‌تر کنند — مسائلی مانند تولید کلیدها یا مدیریت مسیرها.

---

### این قابلیت چیست؟

انواع رشته‌ای قالب‌دار در TypeScript این امکان را می‌دهند که رشته‌هایی با ساختار پویا بسازیم، با استفاده از ساختار ${} برای ترکیب بخش‌های مختلف. این کار به تعریف انواع دقیق‌تر، ایمن‌تر و انعطاف‌پذیرتر کمک می‌کند.

#### نمونه:

type Key = `${string}_action`;


در اینجا، نوع Key می‌تواند هر رشته‌ای باشد که با _action پایان می‌یابد.

---

### 🧑‍💻 این ویژگی چه زمانی مفید است؟

#### ✔️ تولید کلیدها:

زمانی که نیاز است چندین کلید با ساختار یکسان تولید شود، می‌توان با استفاده از رشته‌های قالب‌دار، از تکرار و خطاهای احتمالی جلوگیری کرد.

type Prefix = 'user' | 'admin';
type Action = 'create' | 'edit' | 'delete';

type ActionKey = `${Prefix}_${Action}`;
// 'user_create' | 'admin_edit' | و مانند آن‌ها


---

#### ✔️ کار با مسیرها و URLها:

در مواردی که نیاز است مسیرهایی با بخش‌های پویا تعریف شوند — مانند مسیرهای کاربری یا API.

type UserProfileUrl = `users/${string}/profile`;
// 'users/۱۲۳/profile' | 'users/john/profile' و غیره


---

#### ✔️ تولید مقادیر خاص و کنترل‌شده:

زمانی که بخواهیم رشته‌هایی با الگوهای خاص و پیشوندهای مشخص داشته باشیم و سایر مقادیر را مجاز ندانیم.

---

### جمع‌بندی:

استفاده از رشته‌های قالب‌دار در TypeScript این امکان را فراهم می‌کند که رشته‌هایی با ساختار مشخص و الگوهای ثابت را با دقت و ایمنی بالا نوع‌دهی کنیم. این ویژگی به‌ویژه در پروژه‌هایی که نیاز به کار با داده‌های پویا اما ساختاریافته دارند، بسیار کاربردی است و خطاهای رایج را به حداقل می‌رساند. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
‏### Visual Viewport API: ردیابی بزرگ‌نمایی و تغییرات ناحیه‌ی دید 🤩

اگر تا به حال به این فکر کرده‌اید که چطور می‌توان تغییرات در بزرگ‌نمایی (zoom) صفحه یا واکنش به تغییر ابعاد پنجره در دستگاه‌های موبایل را شناسایی کرد، خبر خوبی برایتان دارم — من به‌تازگی با API جالبی به نام Visual Viewport API آشنا شدم! 🎉

‏**Visual Viewport API** ابزاری است که به شما امکان می‌دهد بفهمید کاربر در حال حاضر سایت شما را *چگونه می‌بیند* و بتوانید رابط کاربری را متناسب با اقدامات او تنظیم کنید.

این API به شما دسترسی می‌دهد به ناحیه‌ی دید بصری — یعنی آن بخش از صفحه که در لحظه روی نمایشگر دیده می‌شود، نه کل محتوای صفحه.

---

### با Visual Viewport API چه اطلاعاتی می‌توان به‌دست آورد؟

#### 🔍 ردیابی بزرگ‌نمایی (Zoom)

از طریق ویژگی window.visualViewport.scale می‌توان تغییرات در سطح بزرگ‌نمایی صفحه را شناسایی کرد. هر زمان کاربر صفحه را بزرگ‌تر یا کوچک‌تر کند، این مقدار به‌روز می‌شود.

---

#### 📏 تغییر اندازه‌ی ناحیه‌ی دید

زمانی‌که اندازه‌ی بخش قابل‌مشاهده‌ی صفحه تغییر می‌کند (برای مثال، هنگام بزرگ‌نمایی یا چرخش صفحه‌نمایش)، می‌توان از window.visualViewport.width و window.visualViewport.height برای دریافت ابعاد جدید استفاده کرد. این کار به تطبیق بهتر رابط کاربری با اندازه‌های مختلف کمک می‌کند.

---

#### ➡️ تشخیص جابه‌جایی ناحیه‌ی دید

با استفاده از window.visualViewport.offsetLeft و window.visualViewport.offsetTop می‌توان جابه‌جایی ناحیه‌ی دید را نسبت به ابتدای صفحه پیگیری کرد. این قابلیت برای جای‌گذاری دقیق عناصر روی صفحه بسیار کاربردی است.

---

### پشتیبانی از رویدادهای resize و scroll

این API از رویدادهای resize و scroll نیز پشتیبانی می‌کند، که هنگام تغییر وضعیت ناحیه‌ی دید فعال می‌شوند. این موضوع به شما امکان می‌دهد محتوای رابط کاربری را *به‌صورت لحظه‌ای* به‌روزرسانی کنید — قابلیتی ایده‌آل برای رابط‌های پویا و تعاملی.

---

### جمع‌بندی

با استفاده از Visual Viewport API می‌توانید رابط‌هایی طراحی کنید که نسبت به رفتارهای کاربر مانند بزرگ‌نمایی یا پیمایش (scroll) واکنش نشان دهند. این ویژگی به‌ویژه برای طراحی رابط‌های موبایل بسیار ارزشمند است. 🙂



دموی این قابلیت را می‌توانید در این لینک مشاهده کنید:

🔗 مشاهده کد در CodePen
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
یکی از ویژگی‌های CSS برای جدول‌ها که اغلب نادیده گرفته می‌شود، اما می‌تواند به‌طور چشمگیری کار شما را ساده‌تر کند:

## table-layout — کلیدی برای بهینه‌سازی جدول‌ها

این ویژگی تعیین می‌کند مرورگر چگونه ابعاد ستون‌ها و سطرهای یک جدول را محاسبه کند.

### table-layout دقیقاً چه می‌کند؟

با استفاده از این ویژگی، می‌توان سرعت رندر جدول را افزایش داد و ظاهر آن را تحت کنترل قرار داد.
در حالت پیش‌فرض، مرورگر اندازه‌ی ستون‌ها را بر اساس محتوای درون آن‌ها محاسبه می‌کند. این کار ممکن است مخصوصاً در جدول‌های بزرگ، فرآیند رندر را کند کند.

اما با کمک table-layout می‌توان ابعاد ستون‌ها را به‌صورت ثابت تعیین کرد تا مرورگر دیگر نیازی به محاسبه‌ی آن‌ها نداشته باشد و از همان ابتدا، از اندازه‌های مشخص‌شده استفاده کند.

---

### مقادیر قابل استفاده برای table-layout:

✔️ auto (مقدار پیش‌فرض):
ابعاد ستون‌ها به‌صورت خودکار و بر اساس محتوای آن‌ها تعیین می‌شود.
مناسب برای جدول‌هایی با محتوای پویا، اما ممکن است باعث کاهش سرعت رندر شود.

✔️ fixed:
همه‌ی ستون‌ها دارای عرض ثابت خواهند بود، بدون توجه به محتوای داخلی آن‌ها.
این گزینه رندر جدول را سریع‌تر کرده و کارایی را بهبود می‌بخشد، زیرا مرورگر از ابتدا از اندازه‌های تعیین‌شده استفاده می‌کند.

---

اگر جدول شما شامل داده‌های زیادی است یا به ستون‌هایی با عرض یکسان نیاز دارید، استفاده از table-layout: fixed بهترین انتخاب خواهد بود. 👍

🔗 [نمونه در CodePen](https://codepen.io/katrin_profrontend/pen/zxvKRPo)


#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
3
### بهبود عملکرد رویدادهای پیمایش (Scroll) 👨‍🏫

به‌تازگی با این هشدار مواجه شدم:

> "\[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive."

این پیام باعث شد رویکردم به مدیریت رویدادهای پیمایش را بازبینی کنم.

زمانی که با رویدادهایی مانند پیمایش با ماوس (wheel) یا حرکت لمسی (touchmove) سروکار داریم، معمولاً چالش‌هایی در زمینه‌ی عملکرد (Performance) به وجود می‌آید.
به‌طور پیش‌فرض، مرورگرها می‌توانند رفتار استاندارد (مانند پیمایش) را مسدود کنند، به‌ویژه اگر در تابع پردازشگر از event.preventDefault() استفاده شود.
این مسأله ممکن است باعث تأخیر در واکنش رابط کاربری**، خصوصاً در دستگاه‌های همراه شود. 😔

---

### راه‌حل: استفاده از گزینه‌ی `{ passive: true }` 🤨

با افزودن گزینه‌ی `{ passive: true }` هنگام افزودن شنونده‌ی رویداد (Event Listener)، به مرورگر اطلاع می‌دهیم که قرار نیست رفتار پیش‌فرض را لغو کنیم.
در نتیجه، مرورگر می‌تواند بلافاصله اقدام به انجام رفتار استاندارد (مثل پیمایش) کند و منتظر اجرای کامل کد شما نماند.

```javascript
element.addEventListener('wheel', (event) => {
// کد مربوطه
}, { passive: true });
```

---

### چرا این موضوع اهمیت دارد؟

✔️ **افزایش سرعت واکنش رویدادها

مرورگر بلافاصله پیمایش را آغاز می‌کند و این باعث بهبود پاسخ‌گویی رابط کاربری می‌شود — خصوصاً در تلفن‌های هوشمند و تبلت‌ها.

✔️ عدم انسداد رندر شدن صفحه
با استفاده از { passive: true } مرورگر دیگر منتظر اجرای کامل تابع پردازشگر نمی‌ماند، که این موضوع باعث کاهش تأخیر و افزایش روانی حرکت صفحه می‌شود.

---

### چند نکته‌ی مهم:

۱️⃣ مقدار پیش‌فرض `passive` برابر با false است
یعنی در حالت عادی می‌توان از event.preventDefault() برای لغو رفتار پیش‌فرض استفاده کرد.
اما مرورگرها در مورد برخی رویدادها مانند wheel`، `touchmove و touchstart در سطوحی مثل window`، `document و `document.body`، به‌صورت خودکار passive را برابر با true قرار می‌دهند تا از ایجاد تاخیر جلوگیری شود.

۲️⃣ اگر شما `passive: true` را صراحتاً تعیین کنید و در تابع مربوطه از event.preventDefault() استفاده نمایید، مرورگر این دستور را نادیده خواهد گرفت.

---

### جمع‌بندی:

استفاده از گزینه‌ی { passive: true } یک تغییر ساده اما مؤثر برای بهبود روانی و واکنش‌پذیری اپلیکیشن است — به‌ویژه در سناریوهایی که با پیمایش و تعامل لمسی سروکار داریم.


#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
🔥1
استفاده از await در سطح بالای ماژول‌های ES

نوشتن کدهای ناهمگام (asynchronous) در جاوااسکریپت تا چندی پیش یک محدودیت مهم داشت: کلیدواژه‌ی await تنها درون یک تابع async قابل استفاده بود. این موضوع با معرفی ویژگی Top-Level Await در استاندارد ES2022 تغییر کرد؛ قابلیتی مدرن در ماژول‌های ES که امکان اجرای الگوهای جدیدی از کد ناهمگام را در سطح ماژول فراهم می‌کند.

‏Top-Level Await چیست؟

به‌طور سنتی، دستور await تنها درون توابع async معتبر بود:


//  خطای نحوی (SyntaxError) در خارج از تابع async
const result = await fetchData();


اکنون با استفاده از Top-Level Await، می‌توانید آن را در سطح بالای ماژول ES اجرا کنید:
//  این کد در یک ماژول ES قابل اجرا است
const result = await fetchData();


در گذشته برای استفاده از await در سطح بالا، ناچار بودید آن را درون یک تابع ناهمگام خوداجرا (IIFE) بپیچید:
(async () => {
const result = await fetchData();
})();


با Top-Level Await می‌توانید با چنین کدهای زائد خداحافظی کنید و منطق ناهمگام خود را به‌صورت مستقیم در بالاترین سطح ماژول بنویسید؛ کدی ساده‌تر، خواناتر و تمیزتر.

⚠️ نکته مهم

‏Top-Level Await فقط در ماژول‌های جاوااسکریپت پشتیبانی می‌شود، نه در CommonJS (یعنی require) و نه در تگ‌های <script> سنتی که فاقد ویژگی type="module" هستند (زیرا این حالت در «مد کلاسیک» اجرا می‌شود). همچنین، فایل‌های با پسوند .cjs در Node.js از آن پشتیبانی نمی‌کنند.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
شکستن کلمات همراه با خط تیره 😉

موضوع ساده به نظر می‌رسد — وقتی یک کلمه طولانی در یک خط جا نمی‌شود، باید آن را با خط تیره به خط بعد منتقل کرد. اما چطور این کار را به‌درستی انجام دهیم تا هم ظاهر متن زیبا باشد و هم ساختار آن به‌هم نریزد؟

بیایید بررسی کنیم برای این کار در CSS چه نیاز داریم. ☺️

برای شکستن صحیح کلمات همراه با خط تیره، سه ویژگی اصلی مورد نیاز است:

✔️ overflow-wrap: break-word; — این ویژگی باعث می‌شود کلمات طولانی (مثل نشانی‌های اینترنتی یا اصطلاحات پیچیده) در صورت کمبود فضا به خط بعد منتقل شوند.

✔️ word-break: break-word; — این ویژگی اجازه می‌دهد کلمات در نقاط مناسب نیز شکسته شوند، اگر در یک خط جا نشوند.

✔️ hyphens: auto; — مسئول اضافه کردن خودکار خط تیره هنگام شکستن کلمات است، بر اساس قواعد زبان مورد استفاده.

نمونه کد:

.text {
overflow-wrap: break-word; /* اجازه شکستن کلمات طولانی */
word-break: break-word; /* شکستن کلمات در نقاط مناسب */
hyphens: auto; /* افزودن خودکار خط تیره هنگام شکستن */
}


حالا همه‌چیز طبق قواعد زبان کار خواهد کرد: کلمات همراه با خط تیره شکسته می‌شوند و در عین حال متن، منظم و زیبا باقی می‌ماند. 👍


#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
یادآوری درباره‌ی ‎`.setProperty()` و متغیرهای CSS 😉

همه‌ی ما متد ‎`.setProperty()` می‌شناسیم و معمولاً زمانی به یادش می‌افتیم که لازم باشد یک ویژگی CSS را مستقیماً از طریق JavaScript تغییر دهیم.
اما به‌راحتی می‌توان فراموش کرد که با همین متد می‌توان متغیرهای CSS را نیز تغییر داد — و این در بسیاری موارد بسیار کارآمدتر است.

برای نمونه، یک متغیر سراسری در ‎`:root`‎:

:root {
--main-color: #333;
}


و در JavaScript:

// تغییر خود متغیر، نه ویژگی مستقیم
document.documentElement.style.setProperty('--main-color', '#ff6600');


اکنون تمام عناصری که مقدار color: var(--main-color) دارند، به‌طور خودکار مقدار جدید را دریافت می‌کنند. 👍

کجا استفاده از متغیرها از طریق ‎`.setProperty()`‎ بیش‌تر به چشم می‌آید؟

✔️ انیمیشن‌ها — تنها با تغییر یک متغیر، تمام استایل‌های مرتبط به‌صورت روان و از طریق CSS transition به‌روز می‌شوند.
✔️ استفاده در content — می‌توان متن یا نمادی را در یک متغیر ذخیره کرد و آن را به‌صورت پویا تغییر داد.

.btn::after {
content: var(--btn-label);
}


btn.style.setProperty('--btn-label', '"✓"');


در نتیجه، ‎`.setProperty()`‎ تنها برای تغییر ویژگی‌ها نیست، بلکه ابزاری قدرتمند برای مدیریت متغیرهای CSS نیز به‌شمار می‌رود ⚡️

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
من همیشه فکر می‌کردم توسعه‌ی فرانت‌اند به‌مراتب دشوارتر از بک‌اند است، اما توضیح این موضوع برای سایر توسعه‌دهندگان همیشه سخت بود. امروز خواستم نظر یک مدل زبانی (که به‌نوعی نماینده‌ی «نظر کلی کارشناسان» است) را بررسی کنم.

نتیجه جالب بود:
توسعه‌ی فرانت‌اند برای انسان‌ها سخت‌تر است، زیرا بک‌اند بیشتر ماهیتی ریاضی و مبتنی بر قواعد دارد و درک آن چندان دشوار نیست؛ همه‌چیز با فرمول‌ها و الگوهای قابل پیش‌بینی پیش می‌رود.

اما فرانت‌اند؟ اینجا قیاس بی‌نظیری مطرح شد: زیست‌شناسی!

🔹 مقیاس‌پذیری بک‌اند: شبیه ریاضیات؛ با افزودن نودهای بیشتر، شارد کردن پایگاه داده یا بهینه‌سازی کوئری‌ها، سیستم طبق فرمول‌ها و قوانین قابل‌پیش‌بینی رشد می‌کند.

🔹 تغییرات فرانت‌اند: شبیه زیست‌شناسی؛ جهش‌های کوچک (مثل دستگاه جدید، ویژگی تازه‌ی مرورگر یا نیاز متفاوت در تجربه‌ی کاربری) رفتاری نوظهور، اغلب آشفته و موردی ایجاد می‌کنند که باید تک‌به‌تک با آن‌ها سازگار شد.

زیست‌شناسی بسیار پیچیده‌تر از ریاضیات است — زیرا ریاضیات قانون‌مند و قطعی است، اما زیست‌شناسی پدیده‌ای نوظهور، پر از استثنا، وابسته به زمینه و همواره در حال تغییر.

به همین دلیل است که فرانت‌اند (شبیه زیست‌شناسی) برای انسان‌ها به‌مراتب شلوغ‌تر و دشوارتر به نظر می‌رسد، حتی اگر بک‌اند (شبیه ریاضیات) از نظر انتزاعی ژرف‌تر باشد.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🤔1
استفاده از `distinctUntilChanged` و `debounceTime`: بهینه‌سازی جستجو 👩‍💻

وقتی فرم ایجاد می‌کنیم، مهم است که از ارسال درخواست‌های غیرضروری به سرور جلوگیری کنیم. دو اپراتور RxJS به نام‌های `debounceTime` و `distinctUntilChanged` در این زمینه به ما کمک می‌کنند:

* ✔️ debounceTime اجرای عملیات را با تأخیر انجام می‌دهد.
* ✔️ distinctUntilChanged مقادیر تکراری را نادیده می‌گیرد.

### مثال:

this.searchForm.controls.searchField.valueChanges
.pipe(
debounceTime(300), // صبر می‌کنیم ۳۰۰ میلی‌ثانیه بعد از آخرین ورودی
distinctUntilChanged() // مقادیر تکراری را نادیده می‌گیریم
)
.subscribe(searchTerm => {
console.log('درخواست به سرور:', searchTerm);
this.searchData(searchTerm); // ارسال درخواست
});


### عملکرد هر اپراتور:

⭐️ debounceTime(300) — ارسال درخواست را ۳۰۰ میلی‌ثانیه بعد از آخرین ورودی به تأخیر می‌اندازد. این کار باعث می‌شود برای هر کاراکتر یک درخواست ارسال نشود، که مخصوصاً هنگام تایپ سریع بسیار مفید است.

⭐️ distinctUntilChanged() — تضمین می‌کند که درخواست تنها وقتی مقدار تغییر کند ارسال شود. اگر کاربر همان عبارت جستجو را دوباره وارد کند، درخواست تکراری ارسال نخواهد شد.

---

نتیجه: ترکیب این دو اپراتور به شما کمک می‌کند کنترل بهتری روی درخواست‌ها در فرم‌های جستجو داشته باشید، عملکرد را بهبود بخشید و بار روی سرور را کاهش دهید. 😉


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نحوه تنظیم Autocomplete با گزینه‌های محدود، ولی با امکان وارد کردن مقادیر دلخواه در TypeScript

اخیراً با یک چالش جالب مواجه شدم: می‌خواستم یک نوع (Type) بسازم که هم بتواند هر رشته‌ای را بپذیرد، و هم برای چند مقدار از پیش تعریف‌شده رفتاری خاص داشته باشد.

معمولاً این کار با enum یا اشیاء حل می‌شد، اما یک روش شیک‌تر هم وجود دارد!

### راهکار: استفاده از string & {} در انتهای Union

این تکنیک اجازه می‌دهد نوعی تعریف کنیم که انعطاف‌پذیر باشد و همزمان در Autocomplete گزینه‌های مشخص را پیشنهاد دهد.

#### مثال:

type MyType = 'Option1' | 'Option2' | string & {};


### توضیح:

* MyType می‌تواند هر رشته‌ای را بپذیرد.
* با این حال، Autocomplete تنها 'Option1' و 'Option2' را پیشنهاد می‌دهد.
* دلیلش این است که ترکیب string & {} امکان استفاده از رشته‌ها را حفظ می‌کند ولی پیشنهادها محدود به مقادیر مشخص شده در Union می‌ماند.

---

نتیجه: این روش برای مواقعی مناسب است که می‌خواهید انعطاف نوع را حفظ کنید و همزمان به راحتی بتوانید گزینه‌های از پیش تعریف‌شده را در Autocomplete نمایش دهید. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
اختصارات منطقی در انتساب‌ها در JavaScript 🤔

ECMAScript ۲۰۲۱ سه اپراتور مفید را اضافه کرده است:

✔️ انتساب x ||= y — اگر x مقدار «فالس» داشته باشد → `x = y`؛
✔️ انتساب x ??= y — اگر x مقدار null یا undefined داشته باشد → x = y (صفر، رشته خالی و false حفظ می‌شوند)؛
✔️ انتساب x &&= y — اگر x مقدار «ترو» داشته باشد → x = y.

‼️ نکته مهم: چرا x ||= y و x = x || y همیشه معادل هم نیستند

به طور خلاصه: اپراتورهای اختصاری مقدار سمت چپ انتساب (LHS) را فقط یک بار محاسبه می‌کنند، در حالی که حالت x = x || y ممکن است LHS را دو بار محاسبه کند. این مسئله زمانی مشکل‌ساز می‌شود که LHS فقط یک متغیر ساده نباشد، بلکه یک عبارت شامل فراخوانی‌ها، getterها یا کلیدهای محاسبه‌شده باشد.

👩‍💻 مثال کمینه و قابل بازتولید:

let i = 0;
function getKey() { console.log('getKey'); return 'k' + (++i); }

const a = {};
a[getKey()] ||= 1; // getKey یک بار فراخوانی می‌شود — ایمن

i = 0;
const b = {};
b[getKey()] = b[getKey()] || 1; // getKey دو بار فراخوانی می‌شود — اثر جانبی!


➡️ در عبارت b[...] = b[...] || 1`، `getKey() ممکن است در فراخوانی‌های مختلف کلیدهای متفاوت تولید کند یا اثرات جانبی دیگری داشته باشد — در نتیجه منطق برنامه خراب می‌شود. اما ||= چنین خطری ندارد، چون ارجاع به b[getKey()] فقط یک بار گرفته می‌شود.

نتیجه:
اپراتورهای ||=, ??= و &&= تنها «شیرینی سینتکسی» نیستند؛ بلکه روشی برای جلوگیری از باگ‌های پنهان هستند، به خصوص زمانی که LHS شامل عبارات با اثر جانبی است.

پیشنهاد استفاده:
⏺️ ??= برای مقداردهی پیش‌فرض واقعی،
⏺️ ||= برای زمانی که هر مقدار فالس مدنظر است،
⏺️ &&= برای به‌روزرسانی شرطی. 👍




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
آشنایی با ویژگی rel در تگ <link> و تأثیر مقادیر آن بر رندر صفحه 🤨

تگ <link> برای اتصال منابع خارجی به سند HTML استفاده می‌شود.

ویژگی کلیدی این تگ، rel است که نوع ارتباط با منبع را مشخص می‌کند: این منابع می‌توانند شامل استایل‌ها، فونت‌ها، آیکون‌ها، مانیفست‌ها و موارد دیگر باشند. نحوه پردازش این منابع توسط مرورگر کاملاً وابسته به مقدار این ویژگی است و همین موضوع به طور مستقیم بر رندر صفحه، سرعت بارگذاری و دسترسی‌پذیری آن تأثیر می‌گذارد. 👨‍🏫

در تصاویر بالا، من به تفصیل مقادیر اصلی ویژگی rel و تأثیر آن‌ها بر عملکرد صفحه را بررسی کرده‌ام. ⬆️

توصیه‌های کاربردی:
✔️ فونت و CSS ‌های حیاتی را فوراً بارگذاری کنید (با stylesheet یا preload)؛
✔️ برای منابع از دامنه‌های دیگر از preconnect یا dns-prefetch استفاده کنید؛
✔️ منابع کم‌اهمیت‌تر را می‌توان به صورت غیرهمزمان بارگذاری کرد (prefetch).

نتیجه‌گیری:
استفاده از این تکنیک‌ها به کاهش تاخیرها، کاهش اثر «پرش صفحه» (FOUC) و بهبود تجربه کاربری کمک می‌کند، به‌ویژه در دستگاه‌های موبایل.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
چه‌کار کنیم وقتی خطاها به هم مرتبط هستند؟ 🤨

ما اغلب با خطاهایی در کد مواجه می‌شویم. اما اگر خطا تنها خود خطا نباشد و نتیجه خطای دیگری باشد، چه باید کرد؟

در JavaScript از سپتامبر سال دو هزار و بیست و یک، ابزاری برای مدیریت چنین مواردی معرفی شده است: `cause`. بیایید ببینیم چگونه می‌توان با آن کار کرد. 😁

📚 \`cause\`\` چیست؟

cause یک پارامتر است که به شما اجازه می‌دهد مشخص کنید کدام خطا منجر به خطای فعلی شده است. این کار اشکال‌زدایی و تشخیص مشکل را ساده‌تر می‌کند و یک زنجیره واضح از خطاها ایجاد می‌کند.

مثال استفاده:

try {
throw new Error("بارگذاری فایل موفق نبود");
} catch (err) {
throw new Error("خطا در پردازش درخواست", { cause: err });
}


در اینجا ما یک خطای جدید ایجاد می‌کنیم و خطای اولیه را در `cause` قرار می‌دهیم. این کمک می‌کند بفهمیم چه چیزی منجر به مشکل جدید شده است.

چه زمانی مفید است؟ 🤔

✔️ برای پاکیزگی کد: به جای دستکاری‌های پیچیده در stack، یک راه ساده و قابل فهم.

✔️ برای اشکال‌زدایی: مشخص می‌شود که یک خطا چگونه به خطای دیگر منجر شده است و این کار باعث سرعت یافتن علت مشکل می‌شود.

نمونه خروجی:

Error: خطا در پردازش درخواست
at <anonymous>:4:9
Caused by: Error: بارگذاری فایل موفق نبود
at <anonymous>:2:9


در نهایت، پارامتر `cause` به مرتبط کردن خطاها کمک می‌کند**، که باعث کاهش «سر و صدای اضافی» در کد و **سرعت بخشیدن به فرآیند شناسایی و رفع مشکلات می‌شود. 👍



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1👎1
Screencast of the different caret-shape possible values.webm
960.6 KB
نحو تعریف ویژگی caret-shape بسیار ساده است:

caret-shape: auto | bar | block | underscore;


مقدار اولیه auto است، که به مرورگر اجازه می‌دهد شکل نشانگر را بر اساس استانداردهای پلتفرم در موقعیت‌های مختلف تعیین کند. اما تا کنون همیشه از نشانگر خط عمودی (|) استفاده شده است.

شما می‌توانید نشانگر بلوک (█) یا زیرخط (_)‌ را انتخاب کنید، که برای برخی اپلیکیشن‌ها مانند ویرایشگر کد کاربردی و جلوه‌ای جذاب دارد.

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript