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

🆔@IR_javascript
Download Telegram
راه‌های متعددی برای ریفرش یا بارگذاری مجدد صفحه وجود دارد و هر کدام می‌توانند در موقعیت‌های مختلف مفید باشند. برای مثال، اخیراً با یک منبع اینترنتی برخورد کردم که لیستی کامل از روش‌های مختلف ریفرش صفحه با JavaScript ارائه کرده است: phpied.com
👀

به جای اینکه در صدها روش غرق شویم، بهتر است روی سه روش اصلی و پرکاربرد تمرکز کنیم که بیشترین کنترل را روی ناوبری و به‌روزرسانی صفحه ارائه می‌دهند:

# ریفرش صفحه در JavaScript

### ۱. location.assign(url) — رفتن به URL جدید

متد assign() برای ناوبری به یک URL جدید استفاده می‌شود و صفحه جاری را در تاریخچه مرورگر نگه می‌دارد. یعنی بعد از رفتن به URL جدید، کاربر می‌تواند با دکمه «بازگشت» به صفحه قبلی برگردد.

location.assign('https://example.com');


---

### ۲. location.replace(url) — رفتن بدون ذخیره در تاریخچه

متد replace() شبیه assign() است، اما صفحه فعلی را در تاریخچه مرورگر ذخیره نمی‌کند. بنابراین بعد از رفتن به URL جدید، با دکمه «بازگشت» نمی‌توان به صفحه قبلی بازگشت.

location.replace('https://example.com');


---

### ۳. location.reload() — بارگذاری مجدد صفحه جاری

متد reload() برای ریفرش یا بارگذاری مجدد صفحه جاری استفاده می‌شود.

* بدون پارامتر: صفحه با توجه به کش مرورگر بارگذاری می‌شود
* با پارامتر true: کش نادیده گرفته شده و صفحه دوباره از سرور بارگذاری می‌شود

location.reload();      // بارگذاری مجدد با کش
location.reload(true); // بارگذاری مجدد بدون کش




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1👍1
# استفاده از Custom Highlight API در مرورگرها

اخیراً متوجه شدم که Firefox 140 (ژوئن ۲۰۲۵) از Custom Highlight API پشتیبانی می‌کند، و حالا این ویژگی روی تمام مرورگرهای اصلی در دسترس است. با این API می‌توان به متن‌هایی که در JavaScript با کلاس Range() به دست می‌آوریم، استایل دلخواه اعمال کرد.

برای درک ساده، مراحل اصلی به این صورت است:

1. یک textNode انتخاب کنید.


   const textNode = document.querySelector("p").firstChild;

2. یک Range بسازید و محدوده‌ی شروع و پایان آن را مشخص کنید:


   const range = new Range();
range.setStart(textNode, startIndex);
range.setEnd(textNode, endIndex);

3. با `CSS.highlights.set()`، این Range را به یک نام هایلایت متصل کنید:


   const highlight = new Highlight(range);
CSS.highlights.set("our-highlight", highlight);

4. در CSS با ::highlight(name) آن را استایل دهید:


   ::highlight(our-highlight) {
background-color: yellow;
}


---

## مثال عملی: هایلایت یک کلمه

const WORD_TO_HIGHLIGHT = "wisdom";
const NAME_OF_HIGHLIGHT = "our-highlight";

const textNode = document.querySelector("p").firstChild;
const textContent = textNode.textContent;

const startIndex = textContent.indexOf(WORD_TO_HIGHLIGHT);
const endIndex = startIndex + WORD_TO_HIGHLIGHT.length;

const range = new Range();
range.setStart(textNode, startIndex);
range.setEnd(textNode, endIndex);

const highlight = new Highlight(range);
CSS.highlights.set(NAME_OF_HIGHLIGHT, highlight);


در DevTools می‌توان دید که کلمه "wisdom" با CSS استایل داده شده، بدون اینکه هیچ المنتی در اطراف آن اضافه شود.

---

## چرا مفید است؟

* استایل بدون دستکاری DOM: نیازی به اضافه کردن <span> یا عناصر دیگر نیست، که باعث کاهش وزن DOM و بهبود عملکرد می‌شود.
* کاهش هزینه‌های محاسباتی: اضافه کردن و حذف <span> می‌تواند باعث Reflow و Repaint شود و عملکرد UX را کند کند.
* قابلیت هایلایت چند محدوده‌ای: یک Highlight می‌تواند چند Range را پوشش دهد، که برای مثال می‌توان برای ایجاد یک سیستم جستجو روی متن کاربرد دارد.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
This media is not supported in your browser
VIEW IN TELEGRAM
🌸میلاد رسول مهربانی‌ها پیامبر اعظم (ص)💚
و امام جعفر صادق (ع)💚
این نصیحت را استاد در کتاب آزادی معنوی (ص۲۰۵) از قول امام صادق علیه السلام نقل می‌کنند که البته این استناد در این کلیپ نیامده است.

🔗https://t.me/motahari_ir/4489
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
8👎2
آیا شما هم هنوز برای استفاده از بک‌اسلش در رشته‌های قالب‌بندی‌شده، آن را دو بار تکرار می‌کنید؟ 🔍

چند روز پیش دیدم که شخصی در رشته‌های قالب‌بندی‌شده (template strings) برای کاراکترهای اِسکیپ‌شده مثل \n (خط جدید) یا \t (تب)، بک‌اسلش‌ها (\\) را تکرار می‌کرد. اما راه‌حل بسیار ساده‌تری وجود دارد و آن استفاده از `String.raw` است. 😁

-----

### `String.raw` چیست؟

این متد به شما اجازه می‌دهد تا با رشته‌های قالب‌بندی‌شده به گونه‌ای کار کنید که دنباله‌های اِسکیپ (مانند \n`، `\t`، `\\ و دیگر موارد) به‌صورت «خام» باقی بمانند. یعنی اگر نیاز به نوشتن یک رشته با مسیر فایل یا کاراکترهای خط جدید و تب دارید، `String.raw` بدون نیاز به اِسکیپ‌کردن‌های اضافی، تمام کار را برای شما انجام می‌دهد. 👍

مثال:

const path = `C:\Users\Name\Documents\file.txt`;
console.log(path); // C:UsersNameDocuments ile.txt

const path = String.raw`C:\Users\Name\Documents\file.txt`;
console.log(path); // C:\Users\Name\Documents\file.txt


به جای اینکه هر بک‌اسلش یا کاراکتر خط جدید را دو بار اِسکیپ کنید، همان‌طور که در یک رشته معمولی لازم بود:


const path = `C:\\Users\\Name\\Documents\\file.txt`;
console.log(path); // C:\Users\Name\Documents\file.txt


-----

### مزایای `String.raw`

➡️ با استفاده از `String.raw`**، کد شما تمیزتر و خواناتر می‌شود، زیرا نیازی به اِسکیپ‌کردن دوباره کاراکترهایی مانند `\`، `n` یا `t` ندارید.

**این قابلیت در کجا مفید است؟


* مسیرهای فایل: اگر با مسیرهای ویندوز کار می‌کنید که شامل بک‌اسلش‌های زیادی است، `String.raw` شما را از نوشتن \\ بی‌نیاز می‌کند.
* عبارات باقاعده (Regular Expressions): اگر در الگوهای خود بک‌اسلش یا کاراکترهای خاص زیادی دارید، `String.raw` به جلوگیری از تفسیر این کاراکترها کمک کرده و آن‌ها را به شکل اصلی‌شان حفظ می‌کند.
* رشته‌های چندخطی: زمانی که لازم است کاراکترهای خط جدید یا تب را به‌صورت متن ذخیره کنید، نه اینکه واقعاً خط را بشکنید یا تب ایجاد کنید.

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

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1🔥1
🤔 چطور بین iframe و صفحه اصلی ارتباط برقرار کنیم؟

ارتباط بین iframe و صفحه والد می‌تواند از طریق روش‌های زیر انجام شود:

* متد `postMessage` (بهترین روش)
* دسترسی به window.frames یا window.parent (اگر در همان دامنه باشند)
* انتقال داده‌ها از طریق localStorage یا cookies

---

🟠 `postMessage` – روشی امن برای دامنه‌های مختلف
متد window.postMessage() امکان ارسال پیام بین پنجره‌های مختلف (iframe، popup، تب‌های دیگر) را حتی در صورت قرار داشتن در دامنه‌های مختلف فراهم می‌کند.

---

🚩 ارسال داده از `iframe` به صفحه والد

*کد در iframe (child.html):*

// ارسال پیام به پنجره والد
window.parent.postMessage({ type: "hello", data: "سلام والد!" }, "*");


*کد در صفحه والد (index.html):*

window.addEventListener("message", (event) => {
console.log("پیام دریافت شده از iframe:", event.data);
});


> علامت * در postMessage به این معناست که پیام به هر دامنه‌ای ارسال می‌شود. بهتر است دامنه مشخصی را تعیین کنید، مثلاً:

window.parent.postMessage({ type: "hello" }, "https://example.com");


---

🚩 ارسال داده از والد به `iframe`

*کد در صفحه والد (index.html):*

const iframe = document.getElementById("myIframe");

// منتظر می‌مانیم iframe بارگذاری شود
iframe.onload = () => {
iframe.contentWindow.postMessage({ type: "greeting", data: "سلام iframe!" }, "*");
};


*کد در iframe (child.html):*

window.addEventListener("message", (event) => {
console.log("پیام دریافت شده از والد:", event.data);
});


---

🚩 دسترسی به `window.frames` و `window.parent` *(فقط اگر در همان دامنه باشند)*

اگر iframe و صفحه اصلی در یک دامنه قرار داشته باشند، می‌توان مستقیماً به آبجکت‌های window دسترسی داشت.

صفحه والد → iframe:

const iframe = document.getElementById("myIframe");

// دسترسی به window داخل iframe
iframe.contentWindow.document.body.style.backgroundColor = "lightblue";


iframe → صفحه والد:

console.log(window.parent.document.title); // دسترسی به عنوان صفحه


---

🚩 استفاده از `localStorage` یا `cookies` *(اگر هر دو پنجره در یک دامنه باشند)*

می‌توان داده‌ها را در localStorage یا cookies ذخیره کرد و طرف دیگر آن‌ها را خواند.

نوشتن در localStorage از iframe:

localStorage.setItem("message", "سلام از iframe!");


خواندن localStorage در صفحه والد:

console.log(localStorage.getItem("message")); // "سلام از iframe!"




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
آشنایی با <meta name="viewport"> 🤓

تگ <meta name="viewport"> یک مِتا تگ است که به مرورگرهای موبایل می‌گوید چگونه ابعاد پنجرهٔ دید مجازی (viewport) را تنظیم کنند و صفحه را چگونه مقیاس‌بندی کنند.

بدون این تگ، مرورگرها در تلفن‌های همراه معمولاً صفحه را «مثل نسخه دسکتاپ» (با عرض حدود نهصد و هشتاد پیکسل) رندر می‌کنند و در نتیجه همه چیز بسیار کوچک و فشرده به نظر می‌رسد.

📚 سینتکس پایه‌ای:

<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>


این حالت در اکثر موارد استفاده می‌شود:

* عرض viewport برابر با عرض واقعی صفحه نمایش دستگاه است.
* مقیاس اولیه برابر با صد درصد است.

مقدارهای content را می‌توانید در تصویر بالا مشاهده کنید 😁

👀 تگ <meta name="viewport"> به تنهایی سایت را واکنش‌گرا نمی‌کند**؛ فقط یک «بوم» برای رندر فراهم می‌کند.

**چند نکته کاربردی:


1️⃣ تگ را در `<head>` و تا حد امکان زود قرار دهید.
مرورگر باید قبل از رندر کردن صفحه آن را ببیند.

2️⃣ از `width=device-width, initial-scale=1.0` به‌عنوان پیش‌فرض استفاده کنید.

3️⃣ چند تگ viewport وارد نکنید.
مرورگرها معمولاً تنها یکی را اعمال می‌کنند یا رفتار صفحه غیرقابل پیش‌بینی می‌شود.

و فراموش نکنید که طراحی و مقیاس‌بندی را روی دستگاه‌های واقعی و شبیه‌سازها بررسی کنید 🥰


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🔥2
🚀 AV1؛ آینده‌ی ویدیو روی وب
این نمودار عملکرد چند کُدِک ویدیویی مختلف رو از نظر کیفیت تصویر (VMAF Rating) در برابر نرخ داده (Data Rate) نشون می‌ده.
محور افقی (Data Rate) → نشون‌دهنده‌ی بیت‌ریت یا حجم داده است
محور عمودی (VMAF Rating) → شاخص کیفیت تصویریه که توسط نتفلیکس توسعه داده شده

این نمودار خیلی واضح نشون می‌ده که AV1 کارآمدترین کُدِک فعلیه،

🔹 فرمت جدید AV1 توسط کروم، سافاری و فایرفاکس پشتیبانی می‌شه و می‌تونه حجم فایل‌های ویدیویی رو تا پنجاه درصد کمتر کنه، بدون افت کیفیت.

⚡️ چرا مهمه؟

* بارگذاری سریع‌تر و مصرف کمتر CPU و باتری
* جایگزین عالی برای GIFها (بیست تا چهل برابر سبک‌تر)
* مناسب برای پروژه‌های وب مدرن

🛠 ابزار کار: با چند دستور ساده‌ی FFmpeg می‌شه ویدیوها رو به AV1 تبدیل کرد. برای سازگاری بیشتر، پیشنهاد می‌شه سه نسخه داشته باشید:

1. AV1 برای مرورگرهای مدرن
2. H.264 برای دستگاه‌های قدیمی
3. (اختیاری) HEVC برای برخی آیفون‌ها و مک‌ها

🎯 اگر دنبال کیفیت بالا با حجم کم هستید، وقتشه به AV1 مهاجرت کنید.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
چه اتفاقی می‌افتد اگر به JSON.parse() داده‌ای غیرمعمول بدهیم؟ 🧐

همهٔ ما به پارس کردن رشته‌ها با JSON.parse() عادت کرده‌ایم، اما اگر داده‌ای غیرمعمول مانند null`، `undefined یا یک رشتهٔ خالی به آن بدهیم، چه رخ می‌دهد؟ بیایید بررسی کنیم! 🤔

۱️⃣ JSON.parse(null)

وقتی مقدار null را به JSON.parse می‌دهیم، به سادگی همان null بازگردانده می‌شود:

console.log(JSON.parse(null));  // null


چرا؟ چون null در زمینهٔ JSON به‌عنوان یک مقدار تهی یا خالی در نظر گرفته می‌شود و متد آن را بدون تغییر بازمی‌گرداند. کمی عجیب به نظر می‌رسد، اما کار می‌کند! 🙃

۲️⃣ JSON.parse(undefined)

اما در مورد undefined داستان فرق دارد. این نوع داده JSON معتبر نیست، بنابراین JSON.parse خطا می‌دهد:

console.log(JSON.parse(undefined));  // Uncaught SyntaxError: Unexpected token u in JSON at position 0


نمی‌توان undefined را به JSON معتبر تبدیل کرد و متد بلافاصله خطای نحوی (Syntax Error) را گزارش می‌کند.

۳️⃣ JSON.parse('')

رشتهٔ خالی هم قابل قبول نیست. تلاش برای پارس کردن آن نیز منجر به خطا می‌شود:

console.log(JSON.parse(''));  // Uncaught SyntaxError: Unexpected end of JSON input


دلیل آن این است که رشتهٔ خالی یک مقدار JSON معتبر نیست. JSON.parse انتظار دارد که رشته شامل نوع معتبری از داده‌های JSON باشد. 😁

نتیجه‌گیری:
اگر رشتهٔ ورودی ممکن است خالی باشد یا مقدار undefined داشته باشد، همیشه قبل از استفاده از JSON.parse() آن را بررسی کنید تا از بروز خطاهای ناخوشایند جلوگیری شود. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
Media is too big
VIEW IN TELEGRAM
ویدیو دوبله شده در مورد چگونگی مدیریت صف‌ها و حلقهٔ رویداد (event loop)

مسئول مدیریت ترتیب اجرای کد در جاوااسکریپت با Event Loop است. این حلقه صف‌های مختلفی دارد که کدهای مختلف را در آن‌ها قرار می‌دهد تا به ترتیب اجرا شوند.

#️⃣#tip #dub
👥@IR_javascript_group
🆔@IR_javascript
3
بیایید با یک ویژگی جالب در CSS آشنا شویم: content-visibility 🤨

---

### content-visibility چیست؟

ویژگی content-visibility در CSS به مرورگر اعلام می‌کند که آیا محتوای یک عنصر باید در هنگام بارگذاری اولیه صفحه رندر شود یا خیر. به این ترتیب، زمانی که مرورگر در حال بارگذاری محتوا و نمایش آن بر روی صفحه است، این ویژگی به ما امکان می‌دهد مشخص کنیم که محتوای یک عنصر تنها در صورت نیاز بارگذاری شود. می‌توانید آن را مشابه بارگذاری تنبل (lazy loading) تصور کنید؛ به این معنا که محتوای فرزندان یک عنصر خارج از محدوده دید کاربر، تا زمانی که وارد ناحیه دید (viewport) نشوند، رندر نخواهند شد.

---

###چگونه کار می‌کند؟

وقتی یک عنصر مقدار content-visibility: auto داشته باشد، تا زمانی که وارد ناحیهٔ دید کاربر نشود رندر نمی‌شود. این کار باعث می‌شود مرورگر منابع را برای عناصر نامرئی هدر ندهد.

.element {
content-visibility: auto | hidden | visible;
}


‏hidden: عنصر محتوای خود را نادیده می‌گیرد (مشابه اعمال display: none; روی محتوا).
‏visible: بدون اثر خاص، و عنصر به‌طور معمول رندر می‌شود.
‏auto: عنصر شامل containment در لایه‌بندی، سبک (style) و رنگ‌آمیزی است. مرورگر تصمیم می‌گیرد که آیا این محتوا برای کاربر ضروری است یا نه؛ و در صورتی که ضروری نباشد، آن را نادیده می‌گیرد. با این حال، عنصر همچنان قابل فوکوس، انتخاب و دسترسی از طریق ابزارهایی مانند جابه‌جایی با کلید Tab یا جست‌وجو در صفحه خواهد بود.


اما تفاوت اینجاست که در content-visibility: hidden;، مرورگر وضعیت رندرشده عنصر را کش می‌کند. بنابراین زمانی که این قانون حذف شود، مرورگر نیازی به رندر مجدد از ابتدا ندارد. این ویژگی برای عناصری مناسب است که به‌طور پیش‌فرض پنهان هستند، اما احتمال بالایی وجود دارد که در طول چرخه حیات صفحه نمایش داده شوند (مانند یک مودال پرکاربرد). در این حالت، هنگام نمایش، عنصر بسیار سریع‌تر بارگذاری می‌شود.

در content-visibility: auto می‌توانید این مقدار را مشابه بارگذاری تنبل برای بخش‌های کامل DOM تصور کنید.
اگر عنصری خارج از دید کاربر (زیر خط fold) باشد و مقدار auto داشته باشد، مرورگر هیچ‌یک از محتوای آن را در نظر نمی‌گیرد و رندر آن را به تعویق می‌اندازد. هنگامی که کاربر به آن اسکرول کند، مرورگر محتوا را نقاشی می‌کند. زمان دقیق رندر به تصمیم مرورگر بستگی دارد.
---

### ارتباط با contain-intrinsic-size

این ویژگی معمولاً همراه با contain-intrinsic-size استفاده می‌شود.

🔹 مشکل: وقتی از content-visibility استفاده می‌کنیم، مرورگر ممکن است اندازهٔ دقیق عناصر پنهان را نداند و این می‌تواند موجب به‌هم‌ریختگی چیدمان شود.

🔹 راه‌حل: استفاده از contain-intrinsic-size که یک اندازهٔ حداقلی برای عنصر تعیین می‌کند؛ حتی اگر عنصر دیده نشود. این کار به مرورگر کمک می‌کند تا جای مناسب برای عنصر در چیدمان صفحه از پیش در نظر بگیرد.

مثال:

.image-gallery img {
content-visibility: auto;
contain-intrinsic-size: 200px; /* تعیین اندازهٔ حداقلی */
}


---

### مزایا

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

---

### موارد استفاده

🔘 صفحات بلند با محتوای زیاد (مانند فیدهای خبری یا کاتالوگ محصولات).
🔘 محتوای پویا که در حین پیمایش ظاهر می‌شود.

---

### جمع‌بندی

استفاده از content-visibility روشی ساده برای سرعت بخشیدن به رندر صفحه است. همچنین اگر همراه با contain-intrinsic-size به‌کار رود، می‌توان از مشکلات چیدمان در هنگام پنهان بودن عناصر جلوگیری کرد. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍5
Cornerstone3D ساخت اپلیکیشن‌های تحت وب برای تصویربرداری پزشکی

مجموعه‌ای از کتابخانه‌های جاوااسکریپت که امکان ساخت ابزارهایی مانند نمایشگر سه‌بعدی سی‌تی‌اسکن، نمایشگر و بسیاری موارد دیگر را فراهم می‌آورد. این پروژه امکانات گسترده‌ای دارد و همراه با آموزش‌های فراوان ارائه شده است.

🔗cornerstonejs.org
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👎1🤯1
‏**Mediabunny** یک کتابخانهٔ جاوااسکریپت برای خواندن، نوشتن و تبدیل فایل‌های رسانه‌ای مانند MP4، WebM و MP3 است، مستقیماً در مرورگر اجرا می‌شود. هدف آن ارائهٔ یک مجموعهٔ کامل برای عملیات رسانه‌ای با کارایی بالا روی وب است.

این کتابخانه از صفر و با TypeScript خالص نوشته شده، هیچ وابستگی‌ای ندارد، بسیار سریع است و از قابلیت tree-shaking پشتیبانی کامل می‌کند؛ به این معنا که فقط کدهایی که استفاده می‌کنید وارد پروژه می‌شوند. می‌توان آن را شبیه FFmpeg تصور کرد، اما به‌طور کامل برای وب از پایه ساخته شده است.


🔗https://mediabunny.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
2🔥1
‍‏**Peaks.js نسخهٔ چهار: کامپوننت رابط کاربری برای تعامل با نمودار موج صدا**

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


🔗https://codeberg.org/chrisn/peaks.js
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍2
یک سرور HTTP نمی‌تواند به صورت خودکار یک اتصال به مرورگر برقرار کند؛ بنابراین همیشه مرورگر آغازگر ارتباط است. حالا برای دریافت به‌روزرسانی‌های لحظه‌ای از سرور HTTP چه باید کرد؟

دو رویکرد اصلی وجود دارد:

🔹 مرورگر بار اصلی را بر دوش می‌کشد:

* Polling کوتاه‌مدت (Short Polling): مرورگر به‌طور مکرر درخواست می‌فرستد تا زمانی که داده‌ی جدید را دریافت کند.
* Polling بلندمدت (Long Polling): سرور درخواست را باز نگه می‌دارد و تنها زمانی پاسخ می‌دهد که داده‌ی تازه آماده شود.

🔹 همکاری مرورگر و سرور:

* WebSocket: یک اتصال دائمی و دوسویه برقرار می‌شود. پس از آن، سرور می‌تواند هر زمان داده‌ی جدید را ارسال کند و مرورگر نیز می‌تواند درخواست‌های تازه بفرستد.
* SSE (Server-Sent Events): یک اتصال یک‌طرفه ایجاد می‌شود که در آن فقط سرور می‌تواند داده‌های جدید را برای مرورگر ارسال کند. مرورگر نمی‌تواند درخواست تازه‌ای از همان کانال به سرور بفرستد.

👉 در نتیجه، انتخاب میان این روش‌ها بستگی به نیاز برنامه دارد: اگر ارتباط دوطرفه نیاز باشد، WebSocket بهترین گزینه است؛ اگر کافی است فقط سرور داده‌ها را به‌طور خودکار به مرورگر بفرستد، SSE ساده‌تر و سبک‌تر است.




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
🔹 مقایسه toString() و String() 🤨

یکی از نیازهای رایج در برنامه‌نویسی، تبدیل داده‌ها به رشته است. برای این کار دو رویکرد اصلی وجود دارد: toString() و String(). هرچند عملکرد آن‌ها شبیه به هم است، اما یک تفاوت کلیدی میانشان وجود دارد. بیایید بررسی کنیم! 😁

---

### ۱️⃣ toString() — متد شیء

این متد یک شیء را به رشته تبدیل می‌کند، اما:

✔️ برای انواع اولیه (مانند عدد یا رشته) نمایش متنی آن‌ها را برمی‌گرداند؛
✔️ برای اشیاء (مثل آرایه یا تابع) خروجی به نوع آن وابسته است؛
✔️ در صورت فراخوانی روی null یا undefined خطا تولید می‌کند.

const num = 42;
console.log(num.toString()); // "42"

const arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"

// خطا در null یا undefined
null.toString(); // TypeError


---

### ۲️⃣ String() — تابع سراسری

این یک تابع عمومی برای تبدیل هر نوع داده به رشته است:

✔️ با تمام مقادیر (حتی null و undefined) کار می‌کند؛
✔️ به جای خطا، عبارت "null" یا "undefined" برمی‌گرداند.

console.log(String(42));        // "42"
console.log(String([1, 2])); // "1,2"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"


---

### چند نکته تکمیلی

✔️ برای اشیاء و آرایه‌هایی که متد toString را بازنویسی نکرده‌اند، خروجی پیش‌فرض خواهد بود (مانند "[object Object]" یا "1,2,3"). برای نمایش متفاوت باید متد toString بازنویسی شود؛
✔️ اگر نیاز به سریال‌سازی شیء به JSON دارید، از JSON.stringify() استفاده کنید؛
✔️ در بیشتر مواقع، متد toString() اندکی سریع‌تر از String() است، چون بررسی‌های اضافه ندارد. با این حال، این تفاوت معمولاً ناچیز است و در عملکرد روزمره کد تأثیر محسوسی ندارد.

---

به‌طور معمول، من از toString() استفاده می‌کنم چون ساده و مستقیم است. اما اگر نیاز باشد مقدار null یا undefined را هم پردازش کنم، سراغ String() می‌روم، زیرا بدون ایجاد خطا، به‌خوبی از عهده این کار برمی‌آید. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
تفاوت Imperative و Declarative در جاوااسکریپت

---

### کد دستوری (Imperative)

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

برای نمونه:

فرض کنید تابعی به نام filteredArray داریم که وظیفه‌اش فیلتر کردن یک آرایه است. در حالت دستوری ما با یک حلقه روی آرایه پیمایش می‌کنیم، سپس بررسی می‌کنیم که آیا عدد کمتر از ده است یا نه. اگر کمتر از ده بود، آن را به آرایه‌ای خالی (به نام regularArray) اضافه می‌کنیم.

نمونه کد دستوری:

function filteredArray(arr) {
let regularArray = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < 10) {
regularArray.push(arr[i]);
}
}
return regularArray;
}

console.log(filteredArray([1, 2, 7, 15, 20])); // [1, 2, 7]


در اینجا ما دقیقاً توضیح داده‌ایم که در هر مرحله چه اتفاقی رخ می‌دهد. همین موضوع باعث می‌شود این کدنویسی Imperative (دستوری) باشد.

---

### کد اعلامی (Declarative)

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

همان مثال بالا را در نظر بگیرید. این بار ما همچنان می‌خواهیم اعداد کمتر از ده را فیلتر کنیم، اما به جای نوشتن مراحل، از متد داخلی filter استفاده می‌کنیم:

نمونه کد اعلامی:

function filteredArray(arr) {
return arr.filter(item => item < 10);
}

console.log(filteredArray([1, 2, 7, 15, 20])); // [1, 2, 7]


در اینجا ما فقط گفتیم: «می‌خواهم آرایه‌ای داشته باشم که عناصرش کمتر از ده باشند». بدون آنکه مرحله‌به‌مرحله توضیح دهیم.

---

جمع‌بندی:

* در Imperative شما «چگونگی انجام کار» را با جزئیات بیان می‌کنید.
* در Declarative شما فقط «آنچه می‌خواهید» را بیان می‌کنید و جزئیات را به زبان یا ابزار می‌سپارید.



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
چگونه مرورگر <script> را هنگام ساخت درخت DOM پردازش می‌کند؟ 🧐

هنگامی که مرورگر HTML را تجزیه می‌کند، تگ‌های <script> می‌توانند ساخت DOM را متوقف کنند و این موضوع روی کارایی صفحه تأثیر می‌گذارد. نحوه‌ی کار به شرح زیر است:

1️⃣ اسکریپت‌های هم‌زمان (synchronous) (`<script>` بدون async یا defer)
این اسکریپت‌ها ساخت DOM را تا زمان بارگذاری و اجرای خود متوقف می‌کنند. نتیجه، کند شدن رندر صفحه است.

2️⃣ اسکریپت‌های غیرهم‌زمان (async)
این اسکریپت‌ها هم‌زمان با HTML بارگذاری می‌شوند**، اما **به محض بارگذاری فایل اجرا می‌شوند. ترتیب اجرای آن‌ها پیش‌بینی‌ناپذیر است و ممکن است رندر صفحه را قطع کند.

3️⃣ اسکریپت‌های defer
این اسکریپت‌ها به صورت هم‌زمان بارگذاری می‌شوند اما پس از تجزیه کامل HTML اجرا می‌شوند و ترتیب اجرای آن‌ها همان ترتیب قرارگیری در سند است.

4️⃣ اسکریپت‌های ماژولی (`type="module"`)
این اسکریپت‌ها مانند defer بارگذاری می‌شوند**، اما **در حالت strict اجرا می‌شوند و از import/export پشتیبانی می‌کنند. اجرای آن‌ها پس از بارگذاری HTML انجام می‌شود و از top-level await پشتیبانی می‌کند.

5️⃣ اسکریپت‌های داینامیک (با `document.createElement('script')`)
به طور پیش‌فرض مانند async رفتار می‌کنند.

👩‍🎓 چند توصیه:

✔️ برای اکثر اسکریپت‌ها از defer استفاده کنید تا رندر صفحه مسدود نشود**؛
✔️ برای اسکریپت‌های مستقل (مثلاً اسکریپت‌های تحلیلی) از **async
استفاده کنید؛
✔️ تعداد اسکریپت‌های هم‌زمان در <head> را کمینه کنید — این موضوع بارگذاری صفحه را کند می‌کند.

به یاد داشته باشید، اسکریپت‌ها نه تنها می‌توانند DOM را مسدود کنند**، بلکه روی **رندر صفحه نیز تأثیر می‌گذارند و سرعت بارگذاری و تجربه کاربری را کاهش می‌دهند. استفاده درست از async و defer باعث سرعت بالاتر بارگذاری و رندر بهتر می‌شود. 👍




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1