<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Hedieh</title><link>https://virgool.ir/feed/@hedieh-heydari</link><description>فرانت‌اند دولوپر  | کد تمیز، طراحی دقیق</description><language>fa</language><pubDate>2026-11-11 20:09:04</pubDate><image><url>https://files.virgool.ir/upload/users/4778182/avatar/cgiOFT.jpg</url><title>Hedieh</title><link>https://virgool.ir/@hedieh-heydari</link></image><item><title>فصل ۷ – Dynamic Typing</title><link>https://virgool.ir/@hedieh-heydari/فصل-۷-dynamic-typing-ev1yb7rc0nym</link><description>جاوااسکریپت یه زبان dynamically typed هست — یعنی متغیرها به نوع خاصی محدود نیستن. این یه قدرت بزرگه، ولی همزمان یه منبع بزرگ باگ هم هست. مثلاً:const possiblyNumeric = &#39;203.45&#39;;&#xA;&#xA;function setWidth(width) {&#xA;  width += 20; // انتظار داریم عدد بشه 223.45&#xA;  applyWidth(width);&#xA;}&#xA;&#xA;setWidth(possiblyNumeric); // =&gt; &#39;203.4520&#39; ← رشته!چون یه operand رشته‌ست، + به‌جای جمع، concatenate می‌کنه. همین یه خط ساده منشأ میلیون‌ها ساعت debugging در دنیا بوده.این فصل دو موضوع اصلی رو پوشش می‌ده: تشخیص تایپ و تبدیل تایپ.تشخیص تایپ (Detection)قبل از اینکه بریم سراغ تکنیک‌ها، یه سوال مهم: واقعاً چی رو می‌خوایم تشخیص بدیم؟اغلب فکر می‌کنیم باید تایپ دقیق رو چک کنیم، ولی این می‌تونه کد رو بی‌دلیل rigid کنه. مثلاً این تابع:function registerPeopleForMarathon(people) {&#xA;  if (Array.isArray(people)) {&#xA;    throw new Error(&#39;People is not an array&#39;);&#xA;  }&#xA;  for (let person of people) {&#xA;    if (!(person instanceof Person)) {&#xA;      throw new Error(&#39;Each person should be an instance of Person&#39;);&#xA;    }&#xA;    registerForMarathon(person.id, person.name);&#xA;  }&#xA;}این چک‌ها بیشتر از اینکه کمک کنن، محدودیت می‌سازن. for...of روی هر iterable کار می‌کنه — نه فقط آرایه. و برای person هم، مهم اینه که id و name داشته باشه، نه اینکه حتماً instance از Person باشه.رویکرد بهتر — duck typing:function isIterable(obj) {&#xA;  return obj != null &amp;&amp; typeof obj[Symbol.iterator] === &#39;function&#39;;&#xA;}&#xA;&#xA;function registerPeopleForMarathon(people) {&#xA;  if (!isIterable(people)) {&#xA;    throw new Error(&#39;People is not iterable&#39;);&#xA;  }&#xA;  for (let person of people) {&#xA;    if (!person || !person.name || !person.id) {&#xA;      throw new Error(&#39;Each person should have a name and id&#39;);&#xA;    }&#xA;    registerForMarathon(person.id, person.name);&#xA;  }&#xA;}اگه مثل اردک راه میره و مثل اردک قار قار می‌کنه، اردکه — لازم نیست شناسنامه‌اش رو ببینیم.typeofاولین ابزار تشخیص تایپ، typeof هست:typeof 1;          // =&gt; &#34;number&#34;&#xA;typeof &#39;&#39;;         // =&gt; &#34;string&#34;&#xA;typeof {};         // =&gt; &#34;object&#34;&#xA;typeof function(){}; // =&gt; &#34;function&#34;&#xA;typeof undefined;  // =&gt; &#34;undefined&#34;&#xA;typeof Symbol();   // =&gt; &#34;symbol&#34;&#xA;typeof 0n;         // =&gt; &#34;bigint&#34;&#xA;typeof true;       // =&gt; &#34;boolean&#34;ولی typeof یه دوست ناپایداره — دو تله بزرگ داره:اول اینکه typeof null برابر &#34;object&#34; برمی‌گردونه — یه باگ تاریخی که هرگز درست نشده.دوم اینکه بین انواع مختلف object فرق نمی‌ذاره:typeof [];          // =&gt; &#34;object&#34;&#xA;typeof RegExp(&#39;&#39;); // =&gt; &#34;object&#34;&#xA;typeof {};   تشخیص تایپ‌های مختلفBoolean: معمولاً کافیه مستقیم توی شرط استفاده بشه. اگه می‌خواید مطمئن باشید دقیقاً true یا false هست:if (isEnabled === true) {...}Number: typeof درست کار می‌کنه، ولی NaN و Infinity هم &#34;number&#34; برمی‌گردونن. برای چک کردن عدد معتبر:function isNormalNumber(n) {&#xA;  return typeof n === &#39;number&#39; &amp;&amp; isFinite(n);&#xA;}تفاوت isNaN و Number.isNaN رو هم بدونید:isNaN(&#39;foo&#39;);        // =&gt; true  (اول cast می‌کنه)&#xA;Number.isNaN(&#39;foo&#39;); // =&gt; false (بدون cast)String: ساده‌ترین تشخیص رو داره:typeof &#39;hello&#39;; // =&gt; &#34;string&#34;برای چک کردن اینکه رشته غیرخالیه:function isNonEmptyString(string) {&#xA;  return typeof string === &#39;string&#39; &amp;&amp; string.trim().length &gt; 0;&#xA;}undefined: بهترین راه استفاده از typeof:if (typeof value === &#39;undefined&#39;) {...}یا از void 0 به‌عنوان جایگزین مطمئن:if (value === void 0) {...}null: باید مستقیم چک بشه:if (someValue === null) {...}null یا undefined با هم: صریح‌ترین راه:if (value === null || value === undefined) {...}یه راه کوتاه‌تر هم هست که محبوبه، ولی ممکنه نیت رو مبهم کنه:if (value == null) {...} // هر دو null و undefined رو می‌گیرهArray: از Array.isArray استفاده کنید:if (Array.isArray(value)) {...}ولی اگه فقط می‌خواید روش loop بزنید، بهتره iterable بودنش رو چک کنید.Plain Object: با بررسی [[Prototype]]:function isPlainObject(object) {&#xA;  return Object.getPrototypeOf(object) === Object.prototype;&#xA;}تبدیل تایپ: Casting و Coercionدو نوع تبدیل تایپ داریم:Casting — عمدی و صریح:javascriptNumber(&#39;123&#39;); // =&gt; 123&#xA;String(456);   // =&gt; &#34;456&#34;Coercion — ضمنی و خودکار توسط جاوااسکریپت:1 + &#39;123&#39;;  // =&gt; &#34;1123&#34;  (رشته!)&#xA;[2] * [3];  // =&gt; 6       (عدد!)&#xA;&#39;22&#39; / 2;   // =&gt; 11      (عدد!)coercion چون ضمنیه، می‌تونه منشأ باگ‌های عجیب بشه. همیشه به تایپ operand‌هاتون مطمئن باشید.تبدیل به Booleanهمه مقادیر به Boolean قابل تبدیلن — مگه هفت مقدار falsy.دو روش صریح:Boolean(0);  // =&gt; false&#xA;Boolean(1);  // =&gt; true&#xA;&#xA;!!0;  // =&gt; false&#xA;!!1;  // =&gt; truedouble-bang (!!) یه روش رایجه که ارزش یه مقدار رو به Boolean تبدیل می‌کنه. مفیده وقتی می‌خواید مطمئن بشید تابعتون همیشه Boolean برمی‌گردونه:function isNamePopulated(name) {&#xA;  return !!name;&#xA;}&#xA;isNamePopulated(&#39;&#39;);        // =&gt; false&#xA;isNamePopulated(null);      // =&gt; false&#xA;isNamePopulated(&#39;Sandra&#39;);  // =&gt; trueتبدیل به Stringصریح‌ترین روش، String() هست:String(456);        // =&gt; &#34;456&#34;&#xA;String(true);       // =&gt; &#34;true&#34;&#xA;String(null);       // =&gt; &#34;null&#34;&#xA;String([1, 2, 3]);  // =&gt; &#34;1,2,3&#34;دو روش کوتاه‌تر هم وجود داره، ولی تفاوت ظریفی دارن:&#39;&#39; + 1234;   // =&gt; &#34;1234&#34; (از valueOf استفاده می‌کنه)&#xA;`${1234}`;   // =&gt; &#34;1234&#34; (مستقیم toString رو صدا می‌زنه)این تفاوت وقتی آبجکت شما هم valueOf و هم toString داره، می‌تونه نتایج متفاوت بده. پس همیشه از String() استفاده کنید.تبدیل به Numberصریح‌ترین روش، Number() هست:Number(&#39;10e3&#39;);    // =&gt; 10000&#xA;Number(&#39; 4.6&#39;);   // =&gt; 4.6&#xA;Number(&#39;wat&#39;);    // =&gt; NaN&#xA;Number(false);    // =&gt; 0روش کوتاه‌تر: unary +:+&#39;55.66&#39;; // =&gt; 55.66&#xA;+&#39;foo&#39;;   // =&gt; NaNparseInt و parseFloat هم وجود دارن ولی با احتیاط باید ازشون استفاده کرد:parseInt(&#39;100&#39;, 8);  // =&gt; 64 (octal)&#xA;parseFloat(&#39;42.01&#39;); // =&gt; 42.01parseInt radix رو همیشه صریح بدید — وگرنه ممکنه خودش تصمیم بگیره و نتایج غیرمنتظره بگیرید.ToPrimitiveوقتی جاوااسکریپت می‌خواد یه آبجکت رو به primitive تبدیل کنه، این ترتیب رو دنبال می‌کنه:۱. اگه [Symbol.toPrimitive] داره، ازش استفاده می‌کنه۲. اگه نه، valueOf رو امتحان می‌کنه۳. اگه نه، toString رو صدا می‌زنهconst one = { [Symbol.toPrimitive]: () =&gt; 1, valueOf: () =&gt; 2, toString: () =&gt; 3 };&#xA;const two = { valueOf: () =&gt; 2, toString: () =&gt; 3 };&#xA;const three = { toString: () =&gt; 3 };&#xA;&#xA;1 == one;   // =&gt; true&#xA;2 == two;   // =&gt; true&#xA;3 == three; // =&gt; trueجمع‌بندیdynamic typing جاوااسکریپت یه شمشیر دولبه‌ست. اگه بدونید چطور تشخیص بدید و تبدیل کنید، می‌تونید کد انعطاف‌پذیر و قابل اعتماد بنویسید. اگه ندونید، همون یه خط += می‌تونه ساعت‌ها debugging بشه.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Sun, 13 Sep 2026 12:37:09 +0330</pubDate></item><item><title>فصل ۶ – تایپ‌های Primitive و Built-in در جاوااسکریپت</title><link>https://virgool.ir/@hedieh-heydari/فصل-۶-تایپ-های-primitive-و-built-in-در-جاوااسکریپت-ky0npz7hywlu</link><description>تا اینجا بیشتر درباره اصول و فلسفه کد تمیز حرف زدیم. از این فصل وارد خود زبان میشیم. میخوایم ببینیم جاوااسکریپت از پایه چطور کار میکنه و چه جاهایی میتونه سورپرایزمون کنه.تایپهای Primitiveجاوااسکریپت هفت تایپ primitive داره: Number، String، Boolean، Undefined، Null، BigInt، و Symbol.یه ویژگی مشترک همهشون اینه که immutable هستن — یعنی مقدارشون رو نمیشه مستقیم تغییر داد. وقتی مینویسیم:let name = &#39;simon&#39;;&#xA;name = name.toUpperCase();داریم یه مقدار جدید میسازیم و به متغیر اختصاص میدیم، نه اینکه مقدار اصلی رو تغییر بدیم.یه نکته جالب: primitives در لحظه دسترسی به property، بهصورت موقت توی یه wrapper object پیچیده میشن. به همین خاطره که میتونیم روی یه string متد فراخوانی کنیم — مثل &#39;hello&#39;.toUpperCase().Falsy Valuesدر جاوااسکریپت، هشت مقدار falsy وجود داره:null، undefined، 0، -0، false، &#34;&#34;، 0n، و NaNیه تله رایج اینه که برای چک کردن وجود یه مقدار، فقط به truthiness اتکا کنیم:// خطرناک&#xA;if (person.age) { ... }&#xA;&#xA;// اگه age برابر 0 باشه (مثلاً نوزاد)، این شرط اجرا نمیشه!&#xA;&#xA;// بهتر&#xA;if (person.age !== null &amp;&amp; person.age !== undefined) { ... }Numberجاوااسکریپت اعداد رو با فرمت 64-bit floating-point ذخیره میکنه. این یعنی:اعداد بزرگتر از Number.MAX_SAFE_INTEGER (حدود ۹ کوادریلیون) دقت ندارناعداد اعشاری میتونن غیرمنتظره رفتار کنن:0.1 + 0.2; // =&gt; 0.3000000000000000برای مقایسه اعداد اعشاری باید از Number.EPSILON استفاده کنیم:if (Math.abs(someValue - 0.3) &lt; Number.EPSILON) {&#xA;  // برابرن&#xA;}دو مقدار خاص هم هست: NaN (نتیجه عملیات ریاضی نامعتبر) و Infinity. هر دو از نوع number هستن — که کمی گیجکنندهست.اگه به اعداد بسیار بزرگ یا دقت بالا نیاز دارید (مثلاً در اپلیکیشنهای مالی)، از BigInt استفاده کنید:9007199254740991n + 2n; // =&gt; 9007199254740993n Stringرشتهها رو میشه با سه نوع delimiter نوشت: تککوتیشن، دابلکوتیشن، و بکتیک. بکتیکها (template literals) امکان چندخطی بودن و interpolation رو میدن:const msg = `خریدم ${count} عدد نان به قیمت ${count * price} تومان.`یه موضوع مهم که اغلب نادیده گرفته میشه اینه که جاوااسکریپت از UTF-16 استفاده میکنه. این یعنی بعضی کاراکترها (مثل ایموجیها) دو code unit اشغال میکنن — و length فقط code unitها رو میشماره:&#39;🐼&#39;.length; // =&gt; 2 (نه 1!)این موضوع وقتی داری متن رو truncate میکنی یا میخوای عرض یه رشته رو توی UI نشون بدی، میتونه مشکلساز بشه.Boolean، null، و undefinedBoolean فقط دو مقدار داره: true و false. مراقب باشید که new Boolean(false) یه آبجکته — نه false — و در شرطها مثل true رفتار میکنه!null یعنی «عمداً هیچی». وقتی میدونیم یه مقدار الان موجود نیست، از null استفاده میکنیم.undefined یعنی «هنوز تعریف نشده». نباید مستقیم مقدار undefined بدیم — اگه میخوایم بگیم چیزی موجود نیست، از null استفاده کنیم.یه تله مهم: typeof null برابر &#34;object&#34; برمیگردونه — این یه باگ تاریخی جاوااسکریپته و هیچوقت درست نشده.SymbolSymbol یه مقدار کاملاً یکتا میسازه. بیشتر برای نگهداشتن متادیتای پنهان روی آبجکتها استفاده میشه — کلیدهایی که توی iteration عادی نشون داده نمیشن:const obj = {};&#xA;obj[Symbol(999)] = &#39;یه چیز مخفی&#39;;&#xA;&#xA;for (let key in obj) console.log(key); // چیزی چاپ نمیشهObjectsهر چیزی که primitive نیست، object هست — حتی توابع. سادهترین راه ساختن آبجکت، object literal است:const animal = { name: &#39;Duck&#39;, hobby: &#39;Paddling&#39; };Property Descriptorsهر property سه ویژگی داره: configurable، enumerable، و writable. میشه اینا رو با Object.defineProperty کنترل کرد — ولی مراقب باشید چون تغییرشون میتونه رفتار غیرمنتظره بسازه.Prototypeجاوااسکریپت یه زبان prototype-based هست. هر بار که به یه property دسترسی پیدا میکنید و روی آبجکت وجود نداره، جاوااسکریپت توی [[Prototype]] دنبالش میگرده. همین مکانیزمه که وراثت رو در جاوااسکریپت ممکن میکنه.کلاسهای مدرن جاوااسکریپت هم در واقع روی همین prototype کار میکنن — فقط syntax شیرینتریه:class Engineer {&#xA;  sayHello() {&#xA;    return `Hello, I&#39;m ${this.name}`;&#xA;  }&#xA;}یه قانون مهم: هرگز native prototypeها رو تغییر ندید. اگه میخواید رفتار یه تایپ رو گسترش بدید، یه subclass بسازید:class HeartArray extends Array {&#xA;  join() { return super.join(&#39; ❤ &#39;); }&#xA;}Functionsتوابع در جاوااسکریپت چند شکل مختلف دارن:// Function Declaration (hoisted)&#xA;function myFunc() {}&#xA;&#xA;// Function Expression&#xA;const myFunc = function() {};&#xA;&#xA;// Arrow Function&#xA;const myFunc = () =&gt; {};&#xA;&#xA;// Method Definition&#xA;const obj = { myFunc() {} };نکات مهم:this توی توابع معمولی به آبجکتی که تابع روش فراخوانی شده اشاره میکنه. توی arrow functions، this از scope بیرونی به ارث میرسه — پس برای event handlerهایی که به instance نیاز دارن، arrow function انتخاب خوبیه:class MyComponent {&#xA;  constructor() {&#xA;    this.bindEvents({&#xA;      : () =&gt; {&#xA;        this; // به instance اشاره میکنه ✓&#xA;      }&#xA;    });&#xA;  }&#xA;}Async Functionsتوابع async همیشه یه Promise برمیگردونن و میتونیم توشون از await استفاده کنیم:const userDetails = await getUserDetails(&#39;user1&#39;);Generator Functionsgeneratorها توابعی هستن که میتونن چند بار مقدار برگردونن و بین هر بار pause کنن:function* threePiggies() {&#xA;  yield &#39;This little piggy went to market.&#39;;&#xA;  yield &#39;This little piggy stayed home.&#39;;&#xA;  yield &#39;This little piggy had roast beef.&#39;;&#xA;}Arrays و Iterablesآرایهها سادهترین راه نگهداشتن مجموعهای از مقادیر هستن. برای iteration، امروزه for...of و forEach به جای for سنتی ترجیح داده میشن:for (let friend of friends) { ... }&#xA;friends.forEach((friend, index) =&gt; { ... });Set و WeakSet برای نگهداری مقادیر یکتا استفاده میشن:new Set([1, 2, 3, 3, 2, 1]); // =&gt; Set{ 1, 2, 3 }Iterable Protocol بهتون اجازه میده آبجکتهای custom رو قابل iterate کنید — با تعریف [Symbol.iterator]:const words = {&#xA;  values: [&#39;Coffee&#39;, &#39;Tea&#39;],&#xA;  [Symbol.iterator]: function*() {&#xA;    for (let word of this.values) {&#xA;      yield word.toUpperCase();&#xA;      yield word.toLowerCase();&#xA;    }&#xA;  }&#xA;};&#xA;[...words]; // =&gt; [&#34;COFFEE&#34;, &#34;coffee&#34;, &#34;TEA&#34;, &#34;tea&#34;]Regular ExpressionsRegExp برای تعریف patternهای متنی استفاده میشه:&#39;Orders: #92838 #02812&#39;.match(/\d+/g); // =&gt; [&#34;92838&#34;, &#34;02812&#34;]یه تله مهم: اگه RegExp شما global (g) باشه، متدهای exec() و test() بعد از هر match، lastIndex رو آپدیت میکنن. اگه روی چند string مختلف اجراشون کنید بدون reset کردن، نتایج غیرمنتظره میگیرید:const regex = /[a-z]+/g;&#xA;regex.exec(&#39;monkeys laughing&#39;); // =&gt; [&#34;monkeys&#34;]&#xA;regex.exec(&#39;birds flying&#39;);     // =&gt; [&#34;lying&#34;] ← اشتباه!&#xA;&#xA;// راهحل: قبل از هر exec جدید، lastIndex رو ریست کنید&#xA;regex.lastIndex = 0;&#xA;regex.exec(&#39;birds flying&#39;); // =&gt; [&#34;birds&#34;] ✓جمعبندیاین فصل نشون داد که جاوااسکریپت در ظاهر ساده به نظر میرسه، ولی لایههای زیرینش پر از جزئیاتیه که اگه ندونیم، میتونن باعث باگهای عجیب بشن. دقت اعداد اعشاری، Unicode در رشتهها، رفتار prototype، و lastIndex در regex — همه اینا چیزاییه که یه برنامهنویس جاوااسکریپت باید بدونه.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Sat, 08 Aug 2026 08:39:50 +0330</pubDate></item><item><title>فصل ۵ – نام‌گذاری سخته</title><link>https://virgool.ir/@hedieh-heydari/naming-is-hard-utepr7zdccsc</link><description>یه جمله معروف توی دنیای برنامه‌نویسی هست که می‌گه: «دو تا چیز سخته — invalidate کردن cache و نام‌گذاری.» این فصل درباره دومیشه.پیدا کردن یه اسم همیشه سخت نیست، ولی پیدا کردن یه اسم خوب معمولاً هست. اسم‌ها فقط برچسب نیستن — اون‌ها راهی هستن که از طریقشون مفهوم رو به دیگران منتقل می‌کنیم. یه اسم بد می‌تونه یه انتزاع خوب رو کاملاً بی‌استفاده کنه.یه اسم خوب چه ویژگی‌هایی داره؟سه تا ویژگی اصلی داره:هدف (Purpose): اسم باید بگه این چیز چیکار می‌کنه یا چیه. توابع معمولاً فعلی نام‌گذاری می‌شن مثل getUser یا createAccount، و متغیرها اسمی مثل account یا button. اگه یه اسم نیاز به کامنت داشته باشه که توضیح بده چیه، احتمالاً اسم خوبی نیست.یه نکته مهم اینه که هدف اسم به context هم بستگی داره. مثلاً توی کلاس TenancyAgreement، آرگومان documentId کافیه — نیازی نیست بشه tenancyAgreementSignedDocumentID. context کلاس بقیه رو توضیح می‌ده.مفهوم (Concept): اسم باید ایده پشت چیزی که داری می‌سازی رو هم منتقل کنه. مثلاً وقتی اسم‌های rejectedDeal، acceptedDeal، pendingDeal رو کنار هم می‌بینیم، بدون خوندن یه خط کد می‌فهمیم که یه deal می‌تونه چند حالت مختلف داشته باشه. این قدرت نام‌گذاریه.قرارداد (Contract): هر اسم یه سری انتظار ضمنی با خودش می‌آره. مثلاً:متغیری که با is شروع می‌شه انتظار داریم Boolean باشهمتغیر با حروف بزرگ انتظار داریم constant باشه: DEFAULT_USER_EXPIRYاسم جمع انتظار داریم یه آرایه باشه: elements در مقابل elementتابعی که با get یا find شروع می‌شه انتظار داریم چیزی برگردونهاسمی که با _ شروع می‌شه انتظار داریم private باشهاین قراردادها نوشته نشدن — ولی همه ازشون پیروی می‌کنیم. شکستن این قراردادها باعث سردرگمی می‌شه.آنتی‌پترن‌های نام‌گذاریاسم‌های بی‌دلیل کوتاهکوتاه بودن به خودی خود بد نیست — مشکل اینه که اسم کوتاه اغلب یه چیزی رو پیش‌فرض می‌گیره که همه بدونن. کدی مثل این:برای کسی که این کدبیس رو نمی‌شناسه کاملاً بی‌معنیه. incId، f، x — هیچ‌کدوم چیزی نمی‌گن.اسم‌های بی‌دلیل عجیببعضی وقت‌ها برنامه‌نویس‌ها اسم‌هایی انتخاب می‌کنن که خلاقانه به نظر می‌رسه ولی فقط گیج‌کننده‌ست. مثلاً navigateMeToMountainTop به‌جای redirectToHomePage. اسم عجیب توجه رو از هدف اصلی منحرف می‌کنه.اسم‌های بی‌دلیل طولانیاسم طولانی معمولاً نشونه یه انتزاع گیج‌شده‌ست. مثلاً:اگه اسمت داره خیلی بلند می‌شه، احتمالاً انتزاعت نیاز به بازنگری داره.سلسله‌مراتب و ثباتیکی از بهترین راه‌ها برای نام‌گذاری خوب، استفاده از سلسله‌مراتب (hierarchy) و ثباته.فرض کنید این ساختار فایل رو دارید:└── app/&#xA;    ├── deepClone.js&#xA;    ├── getParamsFromURL.js&#xA;    ├── openModal.js&#xA;    ├── openModalWithTemplate.js&#xA;    ├── setupAppWithCustomConfig.js&#xA;    └── setURL.jsهیچ سلسله‌مراتبی نیست و هر فایل باید همه context رو توی اسمش حمل کنه. با اضافه کردن ساختار:└── app/&#xA;    ├── setup/&#xA;    │   ├── defaultConfig.js&#xA;    │   └── setup.js&#xA;    ├── modal/&#xA;    │   ├── open.js&#xA;    │   └── openWithTemplate.js&#xA;    └── utils/&#xA;        ├── url/&#xA;        │   ├── getParams.js&#xA;        │   ├── get.js&#xA;        │   └── set.js&#xA;        └── obj/&#xA;            └── deepClone.jsناگهان اسم‌ها ساده‌تر می‌شن چون context از ساختار می‌آد، نه از اسم فایل.همین اصل توی کد هم اعمال می‌شه. اگه توی یه تابع هستی، متغیرهات نیازی ندارن اسم تابع رو توی خودشون داشته باشن:ثبات هم به همون اندازه مهمه. اگه داری یه interface می‌سازی، برای یه مفهوم فقط از یه کلمه استفاده کن:تکنیک‌ها و ملاحظاتقراردادهای پایه جاوااسکریپتچند تا قرارداد وجود داره که تقریباً همه قبول دارن:ثابت‌ها: DEFAULT_COMPONENT_COLORکلاس‌ها و constructor ها: MyComponentبقیه چیزها: myComponentInstanceHungarian Notationچون جاوااسکریپت dynamically typed است، بعضی‌ها نوع متغیر رو توی اسمش می‌ذارن. مثلاً elButton به‌جای button، یا nAge به‌جای age.مزایاش: قرارداد و certainty بیشتر. معایبش: اگه نوع متغیر تغییر کنه اسم گمراه‌کننده می‌شه. توصیه کتاب اینه که فقط وقتی واقعاً ابهام وجود داره ازش استفاده کنید — نه همه‌جا.نام‌گذاری توابعاسم تابع باید حالت امری (imperative) داشته باشه — مثل دستور دادن:displayPrompt(y)removeElements(x)generateRandomNumber(x, y)اگه داری qualifier اضافه می‌کنی، اون رو به argument منتقل کن نه به اسم:تکنیک سه اسم بداگه موندی چی اسم بذاری، این تکنیک رو امتحان کن: سه تا اسم بد برای چیزی که داری می‌سازی بنویس — هر چیزی که به ذهنت می‌رسه. بعد اون‌ها رو با هم مقایسه کن و بهترین المان‌ها رو ترکیب کن.مثلاً برای تابعی که username رو در برابر کلمات ممنوعه چک می‌کنه:matchUsernameAgainstForbiddenWordscheckForForbiddenWordConflictsisUsernameReservedWordاز ترکیب این‌ها می‌رسیم به: isUsernameForbiddenWord — که خیلی بهتره از هر سه‌تاشون.جمع‌بندینام‌گذاری هم علمه، هم هنر. سه ویژگی هدف، مفهوم، و قرارداد — به‌علاوه ثبات و سلسله‌مراتب — چارچوبی می‌سازن که باهاشون می‌شه اسم‌های خوب‌تری انتخاب کرد. و اگه گیر کردید، تکنیک سه اسم بد رو امتحان کنید.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Sat, 01 Aug 2026 09:39:25 +0330</pubDate></item><item><title>فصل ۴ – اصول SOLID و دیگر اصول</title><link>https://virgool.ir/@hedieh-heydari/solidandotherprinciples-pjhvitul74ab</link><description>قبل از شروع، یه چیزی رو صادقانه بگم: این فصل از کتاب به‌شدت روی OOP و کلاس‌ها تمرکز داره. اگه مثل من بیشتر تابعی می‌نویسید، ممکنه بخش‌هایی ازش برای پروژه‌های روزمره‌تون خیلی کاربردی نباشه. با این حال، ایده‌های پشت این اصول ارزش دونستن دارن — حتی اگه مستقیم ازشون استفاده نکنید.قانون دمیتر (Law of Demeter)این اصل کمتر شناخته‌شده‌ست ولی به نظرم یکی از مفیدترین‌هاست — صرف‌نظر از اینکه چه سبکی می‌نویسید. سه ایده اصلی داره:یه واحد باید دانش محدودی از واحدهای دیگه داشته باشهیه واحد فقط باید با دوستان نزدیکش صحبت کنهیه واحد نباید با غریبه‌ها صحبت کنهمثال ساده‌اش اینه: فروشنده نباید مستقیم به کیف پول مشتری دست بزنه — باید از خود مشتری بخواد پول بده. این «غریبه» همون کیف پوله که فروشنده نباید باهاش مستقیم کار کنه.همین مفهوم توی کد یعنی: یه تابع نباید با جزئیات پیاده‌سازی لایه‌های پایین‌تر مستقیم درگیر بشه. اگه یه تابع برای نمایش پیام تولد، مستقیم داره با DOM کار می‌کنه، داره با یه «غریبه» حرف می‌زنه. بهتره یه تابع میانی بسازیم که کار DOM رو انجام بده و تابع اصلی فقط با اون حرف بزنه.اصل SOLIDSOLID یه مجموعه از پنج اصل طراحیه که بیشتر برای کدنویسی شی‌گراست. اگه class-based نمی‌نویسید، بعضی‌هاشون شاید مستقیم به کارتون نیان — ولی ایده پشتشون جهان‌شمول‌تره.اصل مسئولیت واحد می‌گه هر چیزی باید فقط یه دلیل برای تغییر داشته باشه. توی کد تابعی هم این معنی داره: یه تابع نباید هم داده رو پردازش کنه، هم نمایشش بده، هم لاگ بزنه.اصل باز-بسته می‌گه کد باید برای توسعه باز و برای تغییر بسته باشه — یعنی بتونیم رفتارش رو گسترش بدیم بدون اینکه کد اصلی رو دستکاری کنیم. توی دنیای تابعی این رو با composition و higher-order functions می‌شه پیاده کرد.اصل جایگزینی لیسکوف بیشتر مربوط به ارث‌بری و کلاس‌هاست — اگه class-based نمی‌نویسید، احتمالاً کمتر باهاش روبرو می‌شید.اصل جداسازی اینترفیس می‌گه هیچ‌کس نباید مجبور بشه به چیزی که استفاده نمی‌کنه وابسته باشه. این رو می‌شه اینطوری خوند: توابع و ماژول‌هاتون رو کوچیک و متمرکز نگه دارید.اصل وارونگی وابستگی می‌گه ماژول‌های سطح بالا نباید مستقیم به جزئیات سطح پایین وابسته باشن — باید یه لایه انتزاع بینشون باشه. این یکی صرف‌نظر از پارادایم، خیلی کاربردیه.اصل انتزاعاین بخش به نظرم جذاب‌ترین قسمت فصله و کاملاً زبان‌نگاره.اصل انتزاع می‌گه: پیاده‌سازی باید از اینترفیس جدا باشه. دو تا هشدار مهم هم داره:DRY — خودت رو تکرار نکن. اگه داری کدی رو کپی می‌کنی، یه چیزی رو کم انتزاع کردی.YAGNI — بهش نیاز نخواهی داشت. از انتزاع بیش از حد هم بپرهیز.جایی بین این دو تا، انتزاع ایده‌آل قراره. انتزاع زیاد یا کد رو بیش از حد پیچیده می‌کنه یا بیش از حد ساده — هر دو بد هستن. انتزاع متعادل دقیقاً همون چیزیه که کاربر نیاز داره، نه کمتر، نه بیشتر.اصول برنامه‌نویسی تابعیاین بخش برای کسایی که تابعی می‌نویسن مستقیم‌ترین و کاربردی‌ترین قسمت فصله.خلوص تابعی یعنی یه تابع فقط بر اساس ورودی‌هاش خروجی بده و هیچ اثر جانبی نداشته باشه. نتیجه‌اش کد قابل پیش‌بینی و راحت برای تسته.تغییرناپذیری یعنی داده نباید تغییر کنه. به‌جای تغییر یه آبجکت، یه نسخه جدید ازش بساز. این مخصوصاً توی دنیای async جاوااسکریپت که داده بین scope‌های مختلف جابجا می‌شه، خیلی مهمه.جمع‌بندیاگه OOP نمی‌نویسید، بخش SOLID این فصل شاید خیلی مستقیم به دردتون نخوره — و این کاملاً طبیعیه. ولی قانون دمیتر، اصل انتزاع، خلوص تابعی و تغییرناپذیری، ایده‌هایی هستن که صرف‌نظر از سبک کدنویسی ارزش نگه داشتن دارن.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Sat, 25 Jul 2026 08:53:24 +0330</pubDate></item><item><title>فصل ۳ – دشمنان کد تمیز</title><link>https://virgool.ir/@hedieh-heydari/فصل-۳-دشمنان-کد-تمیز-wg5c4qrhpkrf</link><description>تا اینجا فهمیدیم کد تمیز چیه و چه اصولی داره. اما دونستن این اصول به‌تنهایی کافی نیست — باید بدونیم چه چیزایی می‌تونن ما رو از نوشتن کد تمیز باز دارن.این «دشمنان» رو نباید دقیقاً به چشم دشمن ببینید. بهتره بهشون به‌عنوان عواملی نگاه کنید که آروم‌آروم کد تمیز رو تحلیل می‌برن.۱. جاوااسکریپتبدترین ویژگی جاوااسکریپت، همزمان بهترینشه. این زبان به‌شکل عجیبی همه‌جا هست و با سرعت زیادی رشد کرده.جاوااسکریپت خیلی انعطاف‌پذیره — می‌خواید شی‌گرا بنویسید؟ تابعی؟ نمونه‌ای؟ همه رو پوشش می‌ده. همین انعطاف باعث شده ورود بهش آسون باشه، ولی همین انعطاف باعث شده که در هزار جهت مختلف کشیده بشه. امروز با انبوهی از فریم‌ورک‌ها، کتابخانه‌ها، و ابزارهای build مواجهیم و انتخاب «راه درست» تقریباً غیرممکن به نظر می‌رسه.اگه این زبان رو درست به‌کار ببرید، با بیانگری‌اش شگفت‌زده می‌شید. و اگه وقت و تلاش بذارید، می‌تونید باهاش کدی بنویسید که از نظر قابل اطمینان بودن با هر زبان دیگه‌ای برابری کنه.۲. مدیریتکد تمیز فقط به سینتکس مربوط نیست؛ به فرهنگی هم بستگی داره که اون رو پرورش می‌ده. وقتی مدیریت رو «دشمن» می‌نامیم، منظور این نیست که مدیرها مقصرن — مشکل اصلی بعضی رویه‌های فرهنگیه.فشار برای ارسال کدددلاین‌ها از نگاه مدیر منطقی به نظر می‌رسن، ولی از نگاه کسی که روی پروژه کار می‌کنه، اغلب یعنی اجبار به مصالحه. اولین چیزی که قربانی می‌شه، کیفیت کده — مستندات نوشته نمی‌شن، تست‌ها حذف می‌شن، معماری نادیده گرفته می‌شه. نتیجه؟ کد پر از باگ، کاربران ناراضی، و توسعه‌دهندگان فرسوده.راه‌حل اینه که تعادلی معقول بین سرعت ارسال و بدهی تکنیکال برقرار بشه. چند راهکار ساده:بدون تست، هیچ ویژگی یا باگ‌فیکسی ارسال نکنیدبدهی تکنیکال رو به‌طور منظم پرداخت کنید — مثلاً یه بار در هفته همه روی بهبود کدبیس تمرکز کننبا ذینفعان صادقانه ارتباط برقرار کنیدمعیارهای بدیه مدیر غیرفنی ممکنه نگران تعداد خطوط کد یا فیچرهای ارسال‌شده باشه. این معیارها گمراه‌کننده‌ان. یه توسعه‌دهنده ممکنه ده روز وقت بذاره تا یه باگ حیاتی رو با یه خط تغییر حل کنه — آیا این بی‌بهره‌وریه؟قانون گودهارت می‌گه:«وقتی یه معیار به هدف تبدیل می‌شه، دیگه معیار خوبی نیست.»به‌جای شمارش خطوط کد، از توسعه‌دهنده‌ها بپرسید چی سرعت‌شون رو کم کرده. به‌جای شمارش فیچرها، کیفیت و تأثیر هر فیچر روی کاربر رو بسنجید.فقدان مالکیتمالکیت یعنی یه فرد یا تیم احساس مسئولیت واقعی نسبت به بخشی از کد داشته باشه. بدون مالکیت، همه‌چیز آروم‌آروم فرو می‌ریزه. با مالکیت درست، کد پایش می‌شه و با یه چشم‌انداز منسجم رشد می‌کنه.فقط مراقب مالکیت افراطی باشید — غرور بیش از حد می‌تونه به فرهنگی لجوجانه تبدیل بشه.۳. خودماناحساس غرور نسبت به کار، طبیعی و حتی لازمه. اما اگه کنترل نشه، ممکنه به جایی برسیم که کد رو برای تحت‌تأثیر قرار دادن دیگران می‌نویسیم — نه برای اینکه خوانا یا نگهداری‌پذیر باشه.خودنمایی با سینتکسمثلاً برای گرد کردن اعشار به پایین، به‌جای:از عملگر بیتی استفاده می‌کنیم:یا مثال دیگه — استفاده از عملگرهای منطقی به‌جای if:کد یعنی انتقال قصد — و ارتباط خوب به شنونده هم مربوطه، نه فقط گوینده.نظرات لجوجانهوقتی دو نفر از تیم هر کدوم یه ابزار متفاوت رو پیشنهاد می‌دن و هیچ‌کدوم حاضر به انعطاف نیستن، نتیجه یه کدبیس بلاتکلیفه. اگه هر دو از خودمحوری بیرون بیان و دیدگاه دیگری رو واقعاً بشنوند، رسیدن به توافق خیلی ساده‌تره.سندرم ایمپاستراحساس «واقعاً لایق این جایگاه نیستم» در دنیای فناوری خیلی شایعه. این احساس باعث می‌شه در تصمیم‌گیری‌ها تردید کنیم یا نگرانی‌های مهم رو با تیم در میان نذاریم.حقیقت اینه: هیچ‌کس همه‌چیز رو بلد نیست. تنوع دانش اعضای یه تیمه که موفقیت پروژه رو رقم می‌زنه.۴. کارگو کالتدر اوایل قرن بیستم، برخی فرهنگ‌های ملانزی شروع به ساختن باند فرود از چوب و گل کردند — به این امید که هواپیماهای غربی برایشان کالا بیاورند. اشتباهشون اینجا بود که «باند فرود» رو علت رسیدن کالا می‌دونستن، نه وسیله‌ای برای هواپیماها.در برنامه‌نویسی، کارگو کالت یعنی کپی کردن الگوها بدون درک واقعی هدف و عملکردشون.کارگو کالت در کدیه برنامه‌نویس می‌خواد یه route جدید به سرور اضافه کنه. این کد رو توی فایل می‌بینه:و برای route جدیدش اینو می‌نویسه:اشتباه! کد اول یه middleware برای کنترل دسترسی بود. کد درست اینه:خطرناک‌ترین نوع کارگو کالت اینه که وقتی وارد یه کدبیس می‌شیم، ناخودآگاه از الگوهای موجود پیروی می‌کنیم — حتی اگه اشتباه باشن — چون فرض می‌کنیم «حتماً دلیلی داشته.»کارگو کالت در ابزارهاهر ماه یه فریم‌ورک جدید با هیاهوی زیاد معرفی می‌شه. قبل از انتخاب هر ابزار جدید، این سؤال‌ها رو بپرسید:آیا برای این مشکل خاص مناسبه؟آیا درست کار می‌کنه و در آینده هم کار خواهد کرد؟آیا ساده و مستنده؟آیا با کدبیس موجود خوب ادغام می‌شه؟جمع‌بندیکد تمیز فقط یه ویژگی کد نیست — یه فرهنگه که باید هم در سطح سازمان و هم در سطح فردی پرورش داده بشه. جاوااسکریپت، فشارهای مدیریتی، غرور شخصی، و کپی‌کاری کورکورانه — هر کدوم به شکل خودشون می‌تونن این فرهنگ رو تضعیف کنن.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Wed, 03 Jun 2026 15:28:52 +0330</pubDate></item><item><title>فصل ۲ – چهار اصل کد تمیز</title><link>https://virgool.ir/@hedieh-heydari/فصل-۲-–-چهار-اصل-کد-تمیز-i3y56mn99t4p</link><description>تو فصل قبل گفتیم که کد نوشتن یعنی حل مسئله برای کاربر. حالا می‌خوایم از همین پایه، چهار اصل اساسی رو بسازیم که هر کد خوبی باید داشته باشه:قابل اعتماد بودن کارایی قابل نگهداری بودن قابل استفاده بودن قابل اعتماد بودن (Reliability):یه کد قابل اعتماد سه ویژگی داره: درست، پایدار، و مقاوم.درستی (Correctness) نیازمندی‌های کد باید مستقیماً از نحوه استفاده کاربر بیان. اول کاربر و مسئله‌اش رو بشناس، بعد از روی اون‌ها نیازمندی‌هایی تعریف کن که بشه مستقلاً تستشون کرد.پایداری (Stability) پایداری یعنی کد در شرایط مختلف و با ورودی‌های متفاوت، همچنان درست کار کنه. جاوااسکریپت توی مرورگر خیلی در معرض این مشکله — چون روی سخت‌افزارها، سیستم‌عامل‌ها، و مرورگرهای مختلف اجرا میشه. بهترین راه تأیید پایداری، نوشتن تست‌هاییه که کد رو در معرض طیف کامل ورودی‌ها قرار بده.مقاومت (Resilience) پایداری بیشتر با ورودی‌های مورد انتظار سر و کار داره، اما مقاومت اینجاست که می‌پرسه: اگه یه اتفاق غیرمنتظره افتاد چی؟مثال خوبش اینه: فرض کن می‌خوای یه فایل MP3 پخش کنی. قبل از اینکه این کارو بکنی، چک کن که مرورگر اصلاً از MP3 پشتیبانی می‌کنه یا نه اگه مرورگر پشتیبانی نکرد، به‌جای اینکه کد بی‌سروصدا خراب بشه، یه مسیر جایگزین فعال میشه — مثل نمایش متن صوتی. بهش میگن graceful degradation یا تخریب ظریف.نکته جالب: وقتی برای شرایط غیرمنتظره آماده میشی، عملاً اون‌ها رو به بخشی از رفتار عادی کدت تبدیل می‌کنی. این یعنی مقاومت به پایداری تبدیل میشه. کارایی (Efficiency)منابع محدودن — وقت و فضا هر دو.زمان: کد باید CPU رو بی‌دلیل مشغول نکنه. ولی مراقب بهینه‌سازی‌های جزئی (micro-optimization) باش — اول اندازه بگیر، بعد روی گلوگاه‌های واقعی کار کن.فضا: داده‌ها روی شبکه جابجا میشن، توی RAM موقتاً نگه داشته میشن، و احتمالاً روی دیسک ذخیره میشن. هدف اینه که فقط فضای لازم رو استفاده کنی و داده رو فقط وقتی که واقعاً لازمه جابجا کنی.زمان و فضا با هم در هم تنیده‌ان — بهینه‌سازی یکی معمولاً روی دیگری هم اثر داره. اصل کلی: فقط کاری که لازمه رو انجام بده، اسراف نکن. قابل نگهداری بودن (Maintainability)کد مثل ماشین نیست که بدون نگهداری زنگ بزنه، ولی بالاخره باید تغییر کنه — باگ‌ها رفع بشن، فیچرها اضافه بشن، و اغلب توسط آدم‌های مختلف. اون‌هایی که روی کد ما کار می‌کنن هم کاربر ما هستن — پس باید بهشون فکر کنیم.سازگاری (Adaptability) بهترین نگهداری اونیه که اصلاً لازم نشه انجام بشه. ولی وقتی تغییر لازمه، دو دشمن اصلی داریم:شکنندگی (Fragility): یه تغییر کوچیک، جاهای به‌ظاهر نامرتبط رو خراب می‌کنه.سختی (Rigidity): برای یه تغییر ساده، باید همه‌جا رو دستکاری کنی.راه‌حل هر دو: ماژولار کردن کد — جدا کردن مسئولیت‌ها به بخش‌های مستقل که کمتر به هم وابسته باشن.آشنایی (Familiarity) کدی که با الگوهای آشنا و قراردادهای رایج نوشته شده، خیلی راحت‌تر فهمیده میشه. بیشتر اپ‌های وب مفاهیم مشترکی دارن — ثبت‌نام، ورود، CRUD — پس نوشتن کد آشنا کار سختی نیست. قابل استفاده بودن (Usability)قابل استفاده بودن یعنی کد و چیزی که ارائه میده، برای همه کاربران — چه کاربر نهایی، چه برنامه‌نویس دیگه — تا جای ممکن ساده و راحت باشه.User Story یه تکنیک مفید برای تعریف کاربردها اینه:به‌عنوان یه {کاربر}، می‌خوام {فلان کار} رو انجام بدم تا {فلان هدف} رو برسم.مثال برای یه اپ مخاطبین:به‌عنوان کاربر، می‌خوام مخاطب جدید اضافه کنم تا بعداً بتونم پیداش کنم.به‌عنوان کاربر، می‌خوام مخاطب رو با فامیلی پیدا کنم تا باهاش تماس بگیرم.طراحی بدیهی (Intuitive Design) کد خوب نباید نیاز به توضیح داشته باشه. مثال‌هایی از الگوهای بدیهی:تابعی که با is شروع میشه، مقدار بولین برمیگردونه.ثابت‌ها با حروف بزرگ نوشته میشن: MAX_SIZEدکمه X یعنی بستندسترس‌پذیری (Accessibility) کاربرها یه جور نیستن. بعضی‌ها مشکلات بینایی دارن، بعضی‌ها روی سخت‌افزار قدیمی کار می‌کنن، بعضی‌ها اختلال یادگیری دارن — و این فقط شامل کاربر نهایی نیست، برنامه‌نویس‌ها هم همینطور. باید برای همه فکر کرد.اگه همه این اصول پیچیده به نظر میان، یه قانون ساده همه رو جمع می‌کنه:همیشه روی کاربر تمرکز کن — همه کاربرها.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Sat, 23 May 2026 22:01:41 +0330</pubDate></item><item><title>فصل ۱ – بخش ۱: چیدن صفحه</title><link>https://virgool.ir/@hedieh-heydari/فصل-۱-–-بخش-۱-چیدن-صفحه-i9sifbampqg7</link><description>مدتیه که دارم کتاب Clean Code in JavaScript رو می‌خونم و تصمیم گرفتم مفاهیمش رو به شکل خلاصه و کاربردی اینجا مرور کنم. تمرکزم روی نکاتیه که واقعاً در عمل به کار میان — نه توضیحات آکادمیک اضافه. این اولین بخشه.جاوااسکریپت از کجا اومد؟جاوااسکریپت رو برندن ایچ در ۱۹۹۵ ساخت. هدف اولیه‌اش ساده بود: یه «زبان چسبنده» که به طراحان وب کمک کنه صفحات HTML رو راحت‌تر دستکاری کنن. این دستکاری از طریق DOM API انجام می‌شه.کمی بعدتر مفهوم DHTML هم مطرح شد که امکاناتی مثل انیمیشن و اعتبارسنجی ورودی رو فراهم کرد. در اون سال کمتر کسی فکر می‌کرد این زبان روزی برای ساخت اپ‌های پیچیده وب یا حتی Node.js استفاده بشه.DHTMLدر ۱۹۹۷ هم جاوااسکریپت توسط سازمان Ecma استانداردسازی شد و با نام ECMAScript شناخته شد. این استاندارد هنوزم توسط کمیته TC39 توسعه پیدا می‌کنه و نسخه‌هاش بر اساس سال نام‌گذاری میشن — مثل ES2020.چرا اصلاً کد می‌نویسیم؟کدنویسی در اصل حل مسئله‌ست. وقتی کد می‌نویسیم داریم یه مسئله پیچیده رو به مجموعه‌ای از مراحل ساده تبدیل می‌کنیم تا کاربر بتونه ازش استفاده کنه.یه نکته مهم اینه که «کاربر» لزوماً کاربر نهایی UI نیست — ممکنه برنامه‌نویس دیگه‌ای باشه که از کد ما استفاده می‌کنه. در هر صورت، کاربر مرکز همه تصمیم‌گیری‌های ماست.مثال کوچیک: فرض کن داری یه تابع برای اعتبارسنجی کد پستی می‌نویسی. اگه مشخص نکنی این کد برای کدوم کشوره، مشکل داری — چون کد پستی آمریکا فقط عددیه، ولی انگلستان شامل حروف هم میشه.اول مسئله رو بشناستا وقتی دقیق ندونی داری چه مسئله‌ای رو حل می‌کنی، پیشرفتی نخواهی داشت. شناخت درست مسئله اولین قدم برای تعریف نیازمندی‌هاست.برای فهمیدن بهتر مسئله می‌تونی از این سؤال‌ها کمک بگیری:کاربر با چه مشکلاتی روبروئه؟الان چطور اون‌ها رو حل می‌کنه؟چه راه‌حل‌هایی وجود داره و هرکدوم چطور کار می‌کنن؟مدل مسئله چیه؟مدل (یا مدل انتزاعی) یه نمای ساده‌شده از واقعیته که توضیح می‌ده یه سیستم چطور کار می‌کنه. ما همیشه در حال ساختن مدل هستیم — و هرچی اطلاعات بیشتری به‌دست بیاریم، مدلمون به واقعیت نزدیک‌تر میشه.کد برای انسان‌ها نوشته میشهیه چیزی که این فصل روش تأکید می‌کنه اینه: درست کار کردن کد کافی نیست. خوانایی و قابل فهم بودنش هم به همون اندازه مهمه.bad codeclean codeاین مفهوم مستقیماً به انتزاع (Abstraction) می‌رسه — وقتی بخشی از پیچیدگی رو پنهان می‌کنیم و یه رابط ساده‌تر ارائه می‌دیم. انتزاع معنادار یعنی دیگران بتونن بدون اینکه لازم باشه جزئیات رو بدونن، از اون بخش استفاده کنن. این یکی از پایه‌های اصلی فناوری مدرنه.abstraction</description><category>Hedieh</category><author>Hedieh</author><pubDate>Sat, 09 May 2026 16:10:26 +0330</pubDate></item><item><title>clean code in javascript</title><link>https://virgool.ir/@hedieh-heydari/clean-code-in-javascript-kgechhvxlo9v</link><description>مقدمهمدتی بود که موقع کار با جاوااسکریپت، بیشتر از قبل به خوانایی و تمیزی کد اهمیت می‌دادم و همین باعث شد سراغ کتاب Clean Code in JavaScript برم.در این مجموعه، قراره مفاهیم و اصول مهم این کتاب رو به شکل خلاصه و کاربردی مرور کنم. تمرکزم بیشتر روی نکاتیه که به نظرم در عمل کمک می‌کنن کدهای خواناتر و قابل نگهداری‌تری بنویسیم.سعی کردم هر بخش رو بدون ورود به جزئیات اضافی و به صورت مرحله‌به‌مرحله بنویسم، طوری که هم برای یادگیری اولیه مفید باشه و هم برای مرور سریع.</description><category>Hedieh</category><author>Hedieh</author><pubDate>Wed, 22 Apr 2026 16:35:28 +0330</pubDate></item></channel></rss>