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

🆔@IR_javascript
Download Telegram
دامِ جاوااسکریپت: مقایسه‌ی ‎`parseInt("")‎ با ‎`Number("")

گاهی ممکن است فکر کنید که ‎`parseInt("")`‎ و ‎`Number("")`‎ رفتار یکسانی دارند.
اما این‌طور نیست، و اگر تفاوت آن‌ها را ندانید، ممکن است باگ‌های عجیبی در برنامه‌تان به‌وجود بیاید — مخصوصاً هنگام کار با پارامترهای URL.

### بیایید رفتار آن‌ها را بررسی کنیم:

parseInt("")     // ← نتیجه: NaN
Number("") // ← نتیجه: ۰


### چه اتفاقی می‌افتد؟

* ‎`parseInt("")`‎ تلاش می‌کند رشته را به‌صورت عددی، کاراکتر به کاراکتر تجزیه کند.
اما چون رشته خالی است، چیزی برای تجزیه وجود ندارد، در نتیجه: `NaN` (یعنی Not a Number).

* ‎`Number("")`‎ بر اساس قوانین داخلی تبدیل نوع در جاوااسکریپت، رشته را به عدد تبدیل می‌کند.
رشته‌ی خالی طبق این قوانین معادل صفر در نظر گرفته می‌شود، در نتیجه: `۰`.

---

### یک مثال کاربردی: صفحه‌بندی کالاها

فرض کنید در وب‌سایت‌تان صفحه‌ای برای نمایش محصولات دارید و آدرس URL به این صورت است:

https://example.com/products?page=&limit=10


پارامترها را این‌طور دریافت می‌کنید:

const params = new URLSearchParams(location.search);
const page = Number(params.get("page"));
const limit = Number(params.get("limit"));


در اینجا:

* ‎`params.get("page")‎ مقدار رشته‌ی خالی (""`) برمی‌گرداند؛
* ‎`Number("")`‎ آن را تبدیل به عدد صفر می‌کند؛
* در نتیجه، صفحه‌ای با شماره‌ی صفر در منطق برنامه جایگزین می‌شود، در حالی‌که چنین صفحه‌ای اصلاً تعریف نشده!

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

---

### راهکار ایمن‌تر:

const pageRaw = params.get("page");
const page = parseInt(pageRaw);
const safePage = Number.isNaN(page) || page < ۱ ? ۱ : page;


در این روش:

* مقدار خام را می‌گیریم؛
* با ‎`parseInt`‎ آن را تبدیل می‌کنیم؛
* اگر نتیجه ‎`NaN`‎ یا عددی کمتر از یک بود، مقدار پیش‌فرض یک را جایگزین می‌کنیم.

این روش قابل‌اعتمادتر است، زیرا ‎`parseInt("")`‎ خروجی `NaN` می‌دهد و به‌وضوح نشان می‌دهد که داده نامعتبر است.

---

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

* ‎`Number("") → ۰`‎ ممکن است به‌ظاهر بی‌دردسر باشد، اما در عمل می‌تواند منطق برنامه را بی‌سروصدا خراب کند.
* ‎`parseInt("") → NaN`‎ به‌روشنی هشدار می‌دهد که داده مشکل دارد.

در جاوااسکریپت، همیشه خطاها فریاد نمی‌زنند!
گاهی با لبخند می‌گویند: «همه‌چی خوبه»، و بعد یک صفر بی‌ربط تحویل‌تان می‌دهند.
و شما می‌مانید با این سؤال:
«چرا هیچ کالایی توی صفحه نمایش داده نمی‌شه؟!» 🤨


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
ماژول‌های مجازی در Vite
در چارچوب Vite، ماژول‌های مجازی سازوکاری هستند که به شما امکان می‌دهند ماژول‌هایی را ایجاد کنید که به صورت فایل فیزیکی در دیسک وجود ندارند، اما می‌توانند در پروژه شما وارد (import) شده و مورد استفاده قرار گیرند.
نحوه عملکرد:
ساختار وارد کردن (Import): شما از ساختار استاندارد وارد کردن ESM برای ارجاع به ماژول‌های مجازی استفاده می‌کنید.
قاعده پیشوند: طبق قرارداد، ماژول‌های مجازی در Vite (و Rollup، که Vite از آن بهره می‌برد) در مسیر وارد کردن کاربر نهایی با پیشوند "virtual:" مشخص می‌شوند.
پلاگین‌ها: پلاگین‌های Vite کلید پیاده‌سازی ماژول‌های مجازی هستند. یک پلاگین درخواست وارد کردن برای یک شناسه ماژول مجازی را رهگیری کرده و محتوای ماژول را فراهم می‌آورد.
حل و فصل داخلی: در داخل، پلاگین‌ها هنگام حل و فصل شناسه ماژول، آن را با یک کاراکتر تهی (\0) پیشوندگذاری می‌کنند. این کار به تمایز ماژول‌های مجازی از فایل‌های عادی کمک کرده و از پردازش نادرست آنها توسط سایر پلاگین‌ها جلوگیری می‌کند.
محتوای ماژول: هوک load پلاگین، محتوای رشته‌ای ماژول مجازی را برمی‌گرداند.
چرا از ماژول‌های مجازی استفاده کنیم؟
ماژول‌های مجازی برای موارد زیر مفید هستند:
انتقال اطلاعات زمان ساخت (build-time): شما می‌توانید داده‌ها یا پیکربندی‌هایی را که در طول فرآیند ساخت تعیین می‌شوند، تولید کرده و تزریق کنید، و آنها را در کد منبع خود در دسترس قرار دهید.
تعامل با پلاگین‌ها: برخی از پلاگین‌ها، مانند vite-plugin-pwa، ماژول‌های مجازی را برای ارائه یک رابط کاربری برای تعامل با عملکرد خود در معرض دید قرار می‌دهند.
ایجاد ماژول‌های سفارشی: می‌توانید ماژول‌های مجازی برای ارائه داده‌ها یا منطق خاصی که برنامه شما به آن نیاز دارد، ایجاد کنید، بدون اینکه مجبور به ایجاد فایل‌های فیزیکی باشید.
مثال:
یک مثال ساده از یک ماژول مجازی در مستندات Vite نمایش داده شده است:
// vite.config.js
export default function myPlugin() {
const virtualModuleId = 'virtual:my-module';
const resolvedVirtualModuleId = '\0' + virtualModuleId;

return {
name: 'my-plugin',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export const msg = "from virtual module"`;
}
},
};
}

سپس، در کد منبع خود، می‌توانید این ماژول مجازی را وارد کنید:
// main.js
import { msg } from 'virtual:my-module';
console.log(msg); // Output: "from virtual module"

در اصل، ماژول‌های مجازی روشی قدرتمند برای تزریق داده‌های پویا یا مختص ساخت (build-specific) به پروژه Vite شما از طریق یک سازوکار وارد کردن استاندارد ارائه می‌دهند.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
هفت تکنیک قدرتمند وراثت در زبان JavaScript

در زبان JavaScript، وراثت یکی از راهکارهای کلیدی برای بازاستفاده از کد و مدیریت روابط پیچیده میان اشیاء محسوب می‌شود. این زبان با تکیه بر مدل مبتنی بر نمونه‌اولیه (Prototype)، الگوهای گوناگونی برای پیاده‌سازی وراثت ارائه می‌دهد که هر یک مزایا و کاربردهای منحصربه‌فردی دارند. در این راهنما به بررسی این تکنیک‌ها می‌پردازیم و موارد استفاده‌ی مناسب برای هر یک را معرفی می‌کنیم.

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

---

### ۱. وراثت زنجیره‌ای از طریق نمونه‌اولیه (Prototype Chain Inheritance)

وراثت زنجیره‌ای یکی از ساده‌ترین روش‌های وراثت در JavaScript به شمار می‌آید. در این الگو، یک شیء می‌تواند از طریق زنجیره‌ای از نمونه‌اولیه‌ها، به ویژگی‌ها و متدهای شیء والد دسترسی پیدا کند.

نمونه کد:

function Animal() {
this.species = 'پستاندار';
this.habits = ['خواب', 'غذا خوردن'];
}
function Dog() {
this.breed = 'بولداگ';
}
Dog.prototype = new Animal();

let d1 = new Dog();
let d2 = new Dog();
d1.habits.push('پارس کردن');


مزایا:
راه‌اندازی ساده؛ دسترسی کامل زیرکلاس‌ها به متدهای نمونه‌اولیه‌ی والد.

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

---

### ۲. وراثت سازنده (Constructor Inheritance)

در این روش، ویژگی‌های شیء والد با فراخوانی مستقیم سازنده‌ی آن درون سازنده‌ی فرزند، به فرزند منتقل می‌شود.

نمونه کد:

function Animal(species) {
this.species = species;
this.activities = [];
}
function Dog(breed) {
Animal.call(this, 'پستاندار');
this.breed = breed;
}


مزایا:
هر نمونه، ویژگی‌های مستقل خود را دارد؛ امکان ارسال پارامتر به شیء والد وجود دارد.

معایب:
متدها بین نمونه‌ها به اشتراک گذاشته نمی‌شوند و این امر می‌تواند منجر به افزونگی در کد شود.


### ۳. وراثت ترکیبی (Composite Inheritance)

وراثت ترکیبی، دو روش وراثت زنجیره‌ای و سازنده را با یکدیگر تلفیق می‌کند تا هم ویژگی‌های منحصر‌به‌فردی به زیرکلاس‌ها بدهد و هم امکان استفاده از متدهای شیء والد را فراهم سازد.

نمونه کد:

function Animal(species) {
this.species = species;
this.activities = [];
}
Animal.prototype.getSpecies = function () {
return this.species;
};
function Dog(breed) {
Animal.call(this, 'پستاندار');
this.breed = breed;
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;


مزایا:
زیرکلاس‌ها دارای ویژگی‌های خاص خود و دسترسی به متدهای نمونه‌اولیه والد هستند.

معایب:
سازنده‌ی والد دو بار فراخوانی می‌شود که این موضوع منجر به افزایش سربار اجرایی می‌گردد.

---

### ۴. وراثت انگلی (Parasitic Inheritance)

در این الگو، یک شیء ایجاد، تغییر داده شده و سپس بازگردانده می‌شود. این رویکرد انعطاف‌پذیری زیادی فراهم می‌کند، اما پیچیدگی نیز به همراه دارد.

نمونه کد:

function Animal() {
this.species = 'پستاندار';
this.habits = ['غذا خوردن', 'خوابیدن'];
}
function Dog() {
Animal.call(this);
this.breed = 'بولداگ';
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;


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

معایب:
برای ساختارهای بزرگ وراثتی مناسب نیست.

---

### ۵. وراثت مبتنی بر نمونه‌اولیه (Prototype Inheritance)

در این الگو از تابع Object.create برای ایجاد مستقیم یک شیء جدید با نمونه‌اولیه‌ی مشخص استفاده می‌شود.

نمونه کد:

let animal = {
species: 'پستاندار',
traits: ['خون‌گرم', 'مهره‌دار'],
};
function createClone(obj) {
let clone = Object.create(obj);
clone.getTraits = function () {
return this.traits;
};
return clone;
}
let dog = createClone(animal);


مزایا:
ساده است و نیازی به تعریف سازنده ندارد.

معایب:
تمام نمونه‌ها ویژگی‌های نمونه‌اولیه را به‌صورت مشترک دارند.



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

### ۶. وراثت انگلی ترکیبی (Parasitic Compositional Inheritance)

این روش، نسخه‌ای بهینه‌شده از وراثت ترکیبی است که با استفاده از Object.create از فراخوانی چندباره‌ی سازنده جلوگیری می‌کند.

نمونه کد:

function Animal(species) {
this.species = species;
this.traits = [];
}
function Dog(breed) {
Animal.call(this, 'پستاندار');
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;


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

معایب:
پیاده‌سازی پیچیده‌تر شده و نیاز به محصورسازی بیشتری دارد.

---

### ۷. وراثت مبتنی بر کلاس در ES6 (ES6 Class Inheritance)

با معرفی ES6، زبان JavaScript سینتکسی برای کلاس‌ها ارائه داد که فرآیند وراثت را برای توسعه‌دهندگان آسان‌تر و شهودی‌تر می‌سازد.

نمونه کد:

class Animal {
constructor(species) {
this.species = species;
}
getSpecies() {
return this.species;
}
}

class Dog extends Animal {
constructor(breed) {
super('پستاندار');
this.breed = breed;
}
}


مزایا:
سینتکس تمیز و قابل‌فهم، مشابه زبان‌های شیء‌گرای سنتی.

معایب:
ممکن است نیاز به تبدیل (Transpiling) داشته باشد و در برخی موارد، تفاوت اندکی از نظر عملکرد با روش‌های مبتنی بر نمونه‌اولیه دارد.

---

### جمع‌بندی

انتخاب مناسب‌ترین روش وراثت در JavaScript بستگی به نیازهای پروژه دارد. در حالی که وراثت مبتنی بر کلاس‌های ES6 به‌دلیل خوانایی و سادگی بسیار محبوب است، اما الگوهای مبتنی بر نمونه‌اولیه همچنان نقش پررنگی در توسعه‌ی ماژولار و کارآمد ایفا می‌کنند. درک این تکنیک‌ها به شما کمک می‌کند تا ابزاری متناسب با ساختار و انعطاف‌پذیری مورد نیاز خود را انتخاب کرده و کدی منظم، توسعه‌پذیر و بهینه تولید نمایید.


🔗https://jsdev.space/inheritance-js/
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
برای همگام‌سازی یا انتقال داده‌ها میان تب‌های مختلف مرورگر**، می‌توان از **LocalStorage استفاده کرد.

در فریم‌ورک Vue نیز امکان ایجاد یک پوشش واکنشی (reactive wrapper) بر روی آن وجود دارد.

اما راه‌حلی بسیار ساده‌تر و کارآمدتر هم در دسترس است: استفاده از Broadcast Channel API
[مشاهده در MDN](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API)

با استفاده از این API می‌توان یک کانال ارتباطی ایجاد کرد، در آن پیام ارسال نمود و به پیام‌های دریافتی نیز گوش داد.

### ✳️ نمونه کد:

// ایجاد کانال
const bc = new BroadcastChannel("share_channel");

// ارسال پیام به کانال
bc.postMessage("یک پیام نمونه");

// دریافت پیام از کانال
bc.onmessage = (event) => {
console.log(event);
};


همچنین می‌توان از متد postMessage برای ارتباط میان پنجره‌های باز شده (مانند صفحه ورود) با پنجره والد استفاده کرد؛ به‌صورت زیر:

window.opener.postMessage()


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

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1👌1
iframe چیست؟
<iframe> یا *Inline Frame* یک عنصر HTML است که امکان درج یک صفحه HTML یا یک برنامه وب دیگر را درون سند فعلی فراهم می‌کند.

---

### 🔹 موارد اصلی استفاده از iframe:

* جاسازی محتوای خارجی مانند ویدیوهای YouTube، نقشه‌های Google Maps یا انواع ویجت‌ها
* جداسازی کدهای شخص ثالث (مانند فرم‌های پرداخت بانکی)
* بارگذاری اسناد مانند PDF یا گزارش‌های HTML
* معماری مایکروسرویس و تعامل میان برنامه‌های مستقل

---

### 🔸 نمونه ساده‌ی استفاده از iframe:

<iframe 
src="https://example.com"
width="۶۰۰"
height="۴۰۰"
title="نمونه iframe"
></iframe>


---

### 🔹 ویژگی‌های کلیدی عنصر iframe:
src نشانی محتوایی که درون فریم بارگذاری می‌شود
width / height تعیین عرض و ارتفاع فریم
frameborder ویژگی منسوخ‌شده؛ بهتر است با CSS مدیریت شود (border: none)
allow تعیین مجوزها مانند استفاده از دوربین، میکروفن یا پرداخت
sandbox محدودسازی دسترسی iframe به اسکریپت‌ها، فرم‌ها و منابع دیگر

---

### 🔸 نمونه‌ای از بارگذاری پویا در Vue:

<template>
<div>
<input v-model="iframeUrl" placeholder="یک آدرس وارد کنید (مثلاً https://vuejs.org)" />
<button @click="loadIframe">بارگذاری</button>

<iframe
ref="iframeRef"
:src="currentUrl"
width="۱۰۰%"
height="۵۰۰px"
style="border: none;"
></iframe>
</div>
</template>

<script setup>
import { ref } from 'vue';

const iframeUrl = ref('');
const currentUrl = ref('');
const iframeRef = ref(null);

const loadIframe = () => {
if (!iframeUrl.value.startsWith('http')) {
alert('آدرس باید با http:// یا https:// شروع شود');
return;
}
currentUrl.value = iframeUrl.value;
};
</script>


---

### 🔐 ملاحظات امنیتی iframe:

خطرات احتمالی:

* *حمله XSS* در صورت بارگذاری سایت مخرب
* *نشت داده‌ها* به دلیل دسترسی iframe به پنجره والد

راه‌حل: استفاده از ویژگی sandbox برای محدودسازی دسترسی‌ها

<iframe 
src="https://example.com"
sandbox="allow-scripts allow-same-origin"
></iframe>


گزینه‌های متداول sandbox:

* allow-scripts: اجازه اجرای اسکریپت‌ها
* allow-same-origin: اجازه دسترسی به اطلاعات دامنه‌ی مشابه
* allow-forms: مجوز ارسال فرم‌ها
* allow-popups: امکان باز کردن پنجره جدید

---

### 🧩 نمونه‌های کاربردی واقعی:

#### جاسازی ویدئوی یوتیوب:

<template>
<iframe
width="۵۶۰"
height="۳۱۵"
src="https://www.youtube.com/..."
title="پخش‌کننده ویدیوی YouTube"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</template>


#### جاسازی نقشه گوگل:

<template>
<iframe
width="۶۰۰"
height="۴۵۰"
style="border:0"
loading="lazy"
:src="`https://www.google.com/maps/embed/v1/place....`"
></iframe>
</template>


#### نمایش فایل PDF:

<template>
<iframe
src="/documents/document.pdf"
width="۱۰۰%"
height="۶۰۰px"
></iframe>
</template>


---

### جمع‌بندی

<iframe> ابزاری قدرتمند برای درج محتوای خارجی در صفحات وب است، اما نیازمند مدیریت دقیق امنیتی می‌باشد.

* از ویژگی sandbox برای محدودسازی استفاده کنید
* بارگذاری فریم را با رویداد @load کنترل نمایید
* از postMessage برای برقراری ارتباط بین iframe و پنجره والد بهره بگیرید



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نسبت فشرده‌سازی (Compression Ratio) چیست؟
نسبت فشرده‌سازی، نسبت اندازه داده‌های اولیه به اندازه داده‌های فشرده‌شده است.

### فرمول:

نسبت فشرده‌سازی = اندازه اولیه ÷ اندازه پس از فشرده‌سازی

### مثال:

* فایل اولیه: صد کیلوبایت
* پس از فشرده‌سازی: بیست کیلوبایت
* نسبت فشرده‌سازی: ۱۰۰ ÷ ۲۰ = پنج به یک (یا به‌صورت خلاصه: پنج)

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

---

## فشرده‌سازی در HTTP (مانند Gzip، Brotli، Deflate)

در این روش، سرور فایل‌های متنی (مانند HTML، CSS، JS و JSON) را پیش از ارسال به کاربر، فشرده می‌کند.

### نمونه‌ای از هدر پاسخ HTTP:

Content-Encoding: gzip


---

## فشرده‌سازی تصاویر (WebP، AVIF، JPEG XL)

فرمت‌های تصویری از الگوریتم‌های فشرده‌سازی مختلف استفاده می‌کنند:

* بدون افت کیفیت (Lossless): مانند PNG، WebP در حالت بدون افت
* با افت کیفیت (Lossy): مانند JPEG، WebP، AVIF

### مثال:

* تصویر PNG اولیه: پانصد کیلوبایت
* تصویر WebP فشرده‌شده: صد کیلوبایت
* نسبت فشرده‌سازی: پنج به یک

---

## فشرده‌سازی ویدیو و صدا (H.265، Opus، AAC)

کدک‌های ویدیویی مانند H.265 می‌توانند نسبت فشرده‌سازی ده به یک یا حتی بیشتر داشته باشند، در مقایسه با ویدیوهای خام.

---

## فشرده‌سازی پاسخ‌های API و پایگاه‌های داده

پاسخ‌های JSON در API را می‌توان با gzip یا brotli فشرده کرد. برخی پایگاه‌های داده NoSQL مانند MongoDB از فشرده‌سازی بلادرنگ پشتیبانی می‌کنند.

---

## مقایسه الگوریتم‌های فشرده‌سازی

| الگوریتم | نسبت فشرده‌سازی | سرعت | پشتیبانی در مرورگرها |
| -------- | --------------- | -------------- | ------------------------- |
| Gzip | سه تا شش به یک | سریع | همه مرورگرها |
| Brotli | پنج تا ده به یک | کندتر ولی بهتر | مرورگرهای مدرن |
| Deflate | دو تا پنج به یک | سریع | سازگار با مرورگرهای قدیمی |

---

## فعال‌سازی فشرده‌سازی در سرور

### در Nginx:

gzip on;
gzip_types text/html text/css application/javascript;
gzip_min_length 256;
gzip_comp_level 6; # سطح فشرده‌سازی از یک تا نه


### در Node.js (Express):

const compression = require('compression');
app.use(compression({ level: 6 })); // سطح فشرده‌سازی Gzip


---

## مثال عملی: مقایسه Gzip و Brotli

فرض کنید فایل bundle.js با حجم یک مگابایت داریم:

| الگوریتم | اندازه فشرده‌شده | نسبت فشرده‌سازی |
| --------------- | ------------------- | ----------------------------- |
| بدون فشرده‌سازی | یک مگابایت | یک به یک |
| Gzip (سطح ۶) | دویست کیلوبایت | پنج به یک |
| Brotli (سطح ۱۱) | صد و پنجاه کیلوبایت | حدود شش و شصت و هفت صدم به یک |

نتیجه: Brotli فشرده‌سازی بهتری ارائه می‌دهد، اما مصرف CPU بیشتری دارد.

---

## چگونه نسبت فشرده‌سازی را اندازه‌گیری کنیم؟

### در Chrome DevTools:

۱. تب Network را باز کنید
۲. فایل مورد نظر را انتخاب کنید (مثلاً فایل‌های .js یا .css)
۳. در بخش Header بررسی کنید:

* Content-Length (اندازه پس از فشرده‌سازی)
* X-Original-Size (در صورت ارسال توسط سرور)

### ابزارهای ارزیابی:

* Lighthouse (تب Performance)
* WebPageTest (نمایش میزان صرفه‌جویی در ترافیک)

---

## بهینه‌سازی فشرده‌سازی در پروژه‌های وب

برای فایل‌های استاتیک، از Brotli استفاده کنید (فشرده‌سازی بهتر)
برای محتوای پویا، Gzip گزینه مناسبی است (سرعت بیشتر)
تصاویر را بهینه‌سازی کنید (WebP/AVIF + ابزار Sharp در Node.js)
فایل‌های JS/CSS را پیش از فشرده‌سازی minify کنید (با Terser، CSSNano)
کش‌کردن مناسب با Cache-Control و استفاده از CDN





#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
## نمونه‌ای از بهینه‌سازی پروژه Vue.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import viteCompression from 'vite-plugin-compression';

export default defineConfig({
plugins: [
vue(),
// حالت ساده با Gzip
viteCompression(),

// پیکربندی کامل‌تر برای Brotli + Gzip
viteCompression({
algorithm: 'brotliCompress', // الگوریتم پیش‌فرض 'gzip' است
ext: '.br', // پسوند فایل Brotli
threshold: 10240, // حداقل اندازه فایل (بر حسب بایت)
verbose: true, // نمایش لاگ در حین پردازش
deleteOriginFile: false, // عدم حذف فایل اصلی پس از فشرده‌سازی
filter: /\.(js|css|json|html|ico|svg)(\?.*)?$/i, // الگوی فایل‌های قابل فشرده‌سازی
}),
viteCompression({ algorithm: 'gzip' }), // پشتیبانی هم‌زمان از Gzip
],
build: {
// تنظیمات اضافی برای ساخت
chunkSizeWarningLimit: 1600, // افزایش محدودیت هشدار برای اندازه چانک‌ها
},
});


---

## نتیجه‌گیری

نسبت فشرده‌سازی**، یکی از شاخص‌های کلیدی برای ارزیابی اثربخشی فشرده‌سازی در وب است.
فشرده‌سازی صحیح، موجب افزایش سرعت بارگذاری صفحات و کاهش مصرف ترافیک می‌شود.

* **نسبت مناسب برای متن:
بین پنج تا ده به یک (Brotli)
* برای تصاویر: بین سه تا بیست به یک (WebP/AVIF)
* برای ویدیوها: بین ده تا صد به یک (H.265)



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
مقایسه `parseInt` و `parseFloat`: وقتی «Infinity» به یک تله تبدیل می‌شود 🤨

اخیراً با یک مشکل غیرمنتظره برخورد کردم: در یکی از شبیه‌سازی‌هایم، نتیجه‌ی محاسبات به بی‌نهایت می‌رسید. همه‌ی داده‌ها را به‌صورت رشته در فایل CSV ذخیره می‌کردم و سپس آن‌ها را با استفاده از parseInt تجزیه می‌کردم. تنها یک مقدار "Infinity" باعث شد کل آمار من به‌هم بریزد — و مدت زیادی طول کشید تا بفهمم مشکل از کجاست. 😢

---

### نحوه‌ی عملکرد توابع تجزیه

✔️ `parseInt`

⏺️ نویسه‌ها را از چپ به راست می‌خواند، با یک علامت اختیاری (+ یا –) شروع می‌کند؛
⏺️ بعد از علامت، انتظار یک رقم (صفر تا نه) یا در صورت وجود مبنای عددی خاص، حروف مربوط به آن مبنا را دارد؛
⏺️ با رسیدن به اولین نویسه‌ی نامعتبر، فرایند تجزیه متوقف می‌شود.

مثال‌ها:

parseInt("42px", 10);     // خروجی: ۴۲  
parseInt("10.5", 10); // خروجی: ۱۰
parseInt("Infinity", 10); // خروجی: NaN — چون اولین نویسه حرف است نه رقم


---

✔️ `parseFloat`

⏺️ روندی مشابه دارد، اما علاوه بر آن، نقطه‌ی اعشار (.) و حروف e/E برای نمایی (exponent) را نیز شناسایی می‌کند؛
⏺️ در مشخصات این تابع، "Infinity" (و "-Infinity") به‌عنوان یک مقدار عددی معتبر تعریف شده است.

مثال‌ها:

parseFloat("3.14xyz");     // خروجی: ۳٫۱۴  
parseFloat("1e3"); // خروجی: ۱۰۰۰
parseFloat("Infinity"); // خروجی: Infinity
parseFloat("Infinityxyz"); // خروجی: Infinity — ادامه‌ی رشته نادیده گرفته می‌شود


---

### 👀 تله: "Infinity"

در کدی مانند زیر:

parseFloat("Infinity");    // → Infinity  
parseInt("Infinity", 10); // → NaN


✔️ parseFloat مقدار "Infinity" را به‌عنوان یک عدد خاص تشخیص داده و همان را برمی‌گرداند.
✔️ اما parseInt با مشاهده‌ی نویسه‌ی اول که حرف I است (و نه یک رقم یا علامت)، مستقیماً NaN برمی‌گرداند.

در نتیجه ممکن است هم Infinity دریافت کنید و هم NaN. نکته‌ی مهم این است که بررسی ساده‌ای مثل:

if (!isNaN(value)) { … }


مقدار Infinity را عبور می‌دهد (چون isNaN(Infinity) === false است)، ولی NaN را رد می‌کند.

---

### پس چه باید کرد؟

۱️⃣ بر اساس نوع داده، از تابع مناسب استفاده کنید:

✔️ parseInt → فقط برای اعداد صحیح، بدون حالت‌های خاص؛
✔️ parseFloat → برای اعداد اعشاری، نمایی و مقادیر Infinity یا -Infinity.

۲️⃣ بررسی کنید که مقدار نهایی، محدود و واقعی باشد:

const v = parseFloat(raw);
if (!Number.isFinite(v)) {
// اینجا هم NaN و هم ±Infinity شناسایی و فیلتر می‌شوند
}


در غیر این صورت، بدون بررسی مقدار نهایی و بدون مدیریت صریح "Infinity"، خطر از دست رفتن یا خراب شدن داده‌ها وجود دارد. 🤷🏻‍♀️

---

امیدوارم تجزیه‌گرهای شما همیشه درست و بی‌دردسر کار کنند. 🤝



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
محاسبات اعشاری در رایانه‌ها
زبان برنامه‌نویسی شما مشکلی ندارد؛ این چیزی است که به آن محاسبات با ممیز شناور (Floating Point Math) گفته می‌شود. رایانه‌ها به‌صورت ذاتی تنها می‌توانند اعداد صحیح را ذخیره کنند، بنابراین برای نمایش اعداد اعشاری به روشی خاص نیاز دارند — و این روش همیشه کاملاً دقیق نیست. به همین دلیل است که اغلب مواقع، حاصل جمع صفر ممیز یک (۰٫۱) و صفر ممیز دو (۰٫۲) دقیقاً برابر با صفر ممیز سه (۰٫۳) نخواهد بود.

### چرا چنین اتفاقی می‌افتد؟

این موضوع در واقع پدیده‌ای جالب است. در سیستم عددی مبنای ده (یعنی همان سیستمی که ما انسان‌ها استفاده می‌کنیم)، تنها می‌توان کسرهایی را به‌صورت دقیق نمایش داد که مخرج آن‌ها دارای فاکتورهای اولِ ده باشند. عدد ده تنها دو فاکتور اول دارد: دو و پنج. بنابراین کسری مانند یک دوم (۱/۲)**، **یک چهارم (۱/۴)**، **یک پنجم (۱/۵)**، **یک هشتم (۱/۸) و یک دهم (۱/۱۰) را می‌توان به‌راحتی در این سیستم نمایش داد، زیرا مخرج آن‌ها از همین فاکتورهای اول ساخته شده‌اند.

در مقابل، کسرهایی مانند یک سوم (۱/۳)**، **یک ششم (۱/۶)**، **یک هفتم (۱/۷) و یک نهم (۱/۹) در مبنای ده به‌صورت اعشارهای تکرارشونده نمایش داده می‌شوند، چرا که مخرج آن‌ها شامل فاکتورهای اولی هستند که در ترکیب ده قرار ندارند (مانند سه یا هفت).

### اما در مبنای دودویی (مبنای دو) چطور؟

در سیستم باینری (مبنای دو)، تنها فاکتور اول موجود عدد دو است. بنابراین فقط می‌توان کسرهایی را دقیق نمایش داد که مخرج آن‌ها از فاکتور دو تشکیل شده باشد. در این سیستم، کسری مانند یک دوم (۱/۲)**، **یک چهارم (۱/۴) و یک هشتم (۱/۸) بدون خطا نمایش داده می‌شوند، اما کسرهایی مانند یک پنجم (۱/۵) یا یک دهم (۱/۱۰) به‌صورت اعشار تکرارشونده در می‌آیند.

از آنجا که ۰٫۱ و ۰٫۲ در مبنای ده کسرهایی تمیز و واضح هستند (به ترتیب معادل با ۱/۱۰ و ۱/۵)، اما در مبنای دو که رایانه استفاده می‌کند، به شکل اعشارهای تکرارشونده درمی‌آیند. بنابراین وقتی رایانه عملیات ریاضی بر روی این مقادیر انجام می‌دهد، مقداری خطا و باقی‌مانده ایجاد می‌شود که در هنگام تبدیل به نمایش ده‌دهی (مبنای ده، برای انسان) دیده می‌شود.

### برای نمونه:

وقتی در چند زبان برنامه‌نویسی مختلف حاصل یک بعلاوه دو (۱ + ۲) را به خروجی استاندارد می‌فرستیم، نتیجه همیشه دقیق است — زیرا با اعداد صحیح سروکار داریم. اما وقتی پای اعداد اعشاری مانند ۰٫۱ و ۰٫۲ وسط باشد، این خطاها به چشم می‌آیند.

---

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


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
⛽️ npmgraph: ابزاری برای نمایش گراف وابستگی‌های ماژول‌های npm
[مشاهده در وب‌سایت](https://npmgraph.js.org/)

این ابزار مبتنی بر وب، امکان مشاهده‌ی گراف وابستگی‌های ماژول‌های npm را به شکلی بصری فراهم می‌کند. تنها کافی‌ست نام یک یا چند بسته‌ی npm (یا حتی فایل package.json پروژه‌ی خود) را وارد کنید تا نمایی گرافیکی از وابستگی‌ها، از جمله نقاط تقاطع میان آن‌ها، در اختیارتان قرار گیرد.

شما می‌توانید بسته‌ها را بر اساس معیارهای گوناگون — مانند تعداد نگهدارندگان (maintainers) — رنگ‌بندی کنید. همچنین، امکان دانلود نسخه‌ی برداری (SVG) از نمودارها نیز فراهم است تا بتوانید از آن‌ها در مستندات یا ارائه‌های خود استفاده نمایید.


#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
بیشتر خطاهای نرم‌افزاری ناشی از فرضیاتی هستند که متوجه نبودیم آن‌ها را پذیرفته‌ایم.

من اغلب نیاز دارم به‌سرعت نسخهٔ ماژول‌های نصب‌شده در پوشهٔ node_modules را بررسی کنم. راهکارهای فعلی مانند اجرای دستور npm list هم کند هستند و هم خروجی پراکنده و غیرمتمرکزی ارائه می‌دهند. بررسی نسخهٔ ماژول در فایل package.json آن ماژول نیز وقت‌گیر است و اطلاعاتی دربارهٔ سایر نسخه‌های همان ماژول در پروژه نمی‌دهد.

ابزار qnm این مشکل را حل کرده است. این ابزار، اطلاعاتی سریع و دقیق دربارهٔ ماژول‌های نصب‌شده ارائه می‌دهد. qnm از هر دو ابزار npm و yarn پشتیبانی می‌کند و به شما امکان می‌دهد نسخه‌های ماژول‌های مورد نظر خود را به‌راحتی و با سرعت شناسایی کنید.

#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
‏php-node یک ماژول بومی برای Node است که امکان اجرای برنامه‌های PHP را در محیط Node فراهم می‌کند.

چرا باید چنین کاری کرد؟
برای مهاجرت دادن برنامه‌های قدیمی، ساخت اپلیکیشن‌های ترکیبی PHP و JavaScript، یا حتی اپلیکیشن‌های Node‌ای که به هر دلیلی نیاز دارند بخش‌هایی از منطق خود را از طریق PHP اجرا کنند—مثلاً در ارتباط با وردپرس، همان‌طور که در این مطلب مشاهده می‌کنیم.php-node یک ماژول بومی برای Node است که امکان اجرای برنامه‌های PHP را در محیط Node فراهم می‌کند.

چرا باید چنین کاری کرد؟
برای مهاجرت دادن برنامه‌های قدیمی، ساخت اپلیکیشن‌های ترکیبی PHP و JavaScript، یا حتی اپلیکیشن‌های Node‌ای که به هر دلیلی نیاز دارند بخش‌هایی از منطق خود را از طریق PHP اجرا کنند—مثلاً در ارتباط با وردپرس، همان‌طور که در این مطلب مشاهده می‌کنیم.

#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
2👍1
‌‏DevDocs.io وب‌سایتی است که دسترسی آسان و سریع به مستندات مربوط به فناوری‌ها و زبان‌های برنامه‌نویسی مختلف را فراهم می‌کند. در این سایت، مستندات مربوط به موضوعاتی مانند HTML، CSS، JavaScript، پایتون، روبی، پی‌اچ‌پی، ری‌اکت، ویو‌جی‌اس، نود‌جی‌اس و بسیاری فناوری دیگر گردآوری شده‌اند.

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

خبر خوب اینکه این وب سایت امکان کش کردن مستندات را روی کش مرورگر میدهد و در زمان محدودیت اینترنت می توانید به راحتی به مستندات دسترسی داشته باشید

🔗 https://devdocs.io/offline
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
1
### تاب‌آوری توسعه‌دهندگان فرانت‌اند در شرایط جنگی و محدودیت اینترنت

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

۱. استفاده از مخازن داخلی (Mirror) برای نصب پکیج‌ها
در صورت قطع دسترسی به npm یا سایر ریجیستری‌های خارجی، از آینه‌های داخلی برای نصب پکیج‌ها بهره بگیرید.
🔗 [راهنمای دسترسی به مخزن داخلی npm در اینترنت ملی](https://roocket.ir/discuss/%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D8%A8%D9%87-%D9%85%D8%AE%D8%B1%D9%86-npm-%D8%AF%D8%B1-%D8%A7%DB%8C%D9%86%D8%AA%D8%B1%D9%86%D8%AA-%D9%85%D9%84%DB%8C-%D8%B1%D8%A7%D9%87-%D8%AD%D9%84/)

۲. ورود به سرویس هوش مصنوعی «اول‌ای‌آی» از پیش انجام شود
در زمان‌های بحرانی، دسترسی به حساب ممکن است با مشکل مواجه شود. بهتر است از همین حالا وارد حساب خود شوید.
🔗 [ورود به avalAI](https://chat.avalai.ir/chat)

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

۴. مستندات و پکیج‌های پراستفاده را از قبل دانلود و ذخیره کنید
کتابخانه‌ها و ابزارهایی مانند React، Vue، Next.js، Tailwind و همچنین مستندات مربوط به APIها و ابزارهای توسعه را آفلاین نگهداری کنید. استفاده از ابزارهایی مانند DevDocs [+پست قبلی ]می‌تواند مفید باشد.

۵. استفاده از پیام‌رسان «سروش پلاس» برای ارتباط با خارج از کشور
بر اساس گزارش‌ها، پیام‌رسان سروش امکان ارتباط کاربران خارج از کشور را فراهم کرده است. این گزینه در شرایط خاص می‌تواند جایگزینی موقت باشد.
🔗 [جزئیات بیشتر در زومیت](https://www.zoomit.ir/tech-iran/442373-soroush-plus-confirms-users-outside-of-iran/)

اگر تجربه و یا موضوع دیگری را سراغ دارید در بخش نظرات بیان کنید



#️⃣#discussion
👥@IR_javascript_group
🆔@IR_javascript
👎1
جاوااسکریپت | JavaScript pinned «### تاب‌آوری توسعه‌دهندگان فرانت‌اند در شرایط جنگی و محدودیت اینترنت در شرایطی مانند قطعی اینترنت جهانی یا اینترنت ملی، داشتن آمادگی از پیش می‌تواند مانع از توقف کامل روند توسعه شود. توصیه‌های زیر برای حفظ کارایی و ارتباط در این شرایط پیشنهاد می‌شود: ۱.…»
This media is not supported in your browser
VIEW IN TELEGRAM
امام سجاد علیه‌السلام عموی خود #عباس علیه السلام را چنین توصیف می‌فرماید:
💠 خدا عمویم عباس را رحمت کند که ایثار کرد و خود را به سختی افکند و در راه برادرش جانبازی کرد، تا آن‌که دست‌هایش از پیکر جدا گردید.
⚡️آن‌گاه خداوند به جای آن‌ها دو بال به وی عنایت فرمود که در بهشت همراه فرشتگان پرواز کند؛ همان‌سان که برای جعفر طیار قرار داد.
⚜️ عباس نزد خداوند مقامی دارد که همه شهدا در قیامت بدان غبطه می‌خورند.

#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
10👎6😁1
This media is not supported in your browser
VIEW IN TELEGRAM
Slideout.js

یک کتابخانهٔ سبک برای ایجاد منوهای کشویی جانبی است. این ابزار از حرکات لمسی (سوايپ) پشتیبانی می‌کند، به هیچ‌گونه چارچوب خارجی وابسته نیست و برای طراحی رابط‌های کاربری واکنش‌گرا در دستگاه‌های موبایل و دسکتاپ کاملاً مناسب است.

🔗https://slideout.js.org/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
‏**PDFSlick نسخهٔ سه: مشاهده و تعامل با اسناد PDF در اپلیکیشن‌های JavaScript**

یک نمایشگر کامل و قدرتمند PDF برای اپلیکیشن‌های React، Solid، Svelte و JavaScript خالص است. این ابزار که بر پایهٔ PDF.js توسعه یافته، مجموعه‌ای گسترده از قابلیت‌ها را ارائه می‌دهد—از مشاهدهٔ سادهٔ فایل‌های PDF گرفته تا کار با اسناد متعدد و حجیم همراه با امکان افزودن یادداشت.

نسخهٔ سه این ابزار به PDF.js نسخهٔ پنج ارتقا یافته و اکنون از پروفایل‌های ICC پشتیبانی می‌کند، عملکرد بهتری در نمایش فرمت JPEG 2000 دارد و رندر صفحات بزرگ نیز به‌طور چشمگیری بهبود یافته است.

دمو:
https://pdfslick.dev/examples/pdf-viewer-app




#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
1
This media is not supported in your browser
VIEW IN TELEGRAM
هیهات منا الذله
🖤 سالروز شهادت حضرت اباعبدالله(ع)

🔗 https://t.me/motahari_ir/4452
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
12👎2