<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Ehsan</title>
        <link>https://virgool.io/feed/@ehsan_n</link>
        <description>Github: ehsan-shv?</description>
        <language>fa</language>
        <pubDate>2026-06-07 12:52:45</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1516/avatar/FZKWws.png?height=120&amp;width=120</url>
            <title>Ehsan</title>
            <link>https://virgool.io/@ehsan_n</link>
        </image>

                    <item>
                <title>var VS let VS const</title>
                <link>https://virgool.io/@ehsan_n/var-let-const-kp2bomyabmhy</link>
                <description>همون طور که می‌دونیم استفاده از var keyword تو ورژن قدیمی جاوااسکریپت (ES5) تنها راهی بود که می‌تونستیم متغیرها رو تعریف کنیم.تو ورژن جدیدتر (ES6) دو keyword جدید (let, const) هم اضافه شدن. تو این پست می‌خوایم تفاوت‌ها و شباهت‌های var، let و const رو با هم بررسی کنیم.همین اول کار باید این رو بدونیم که مقدار const برخلاف let و var غیرقابل تغیر هست.const yearOfBorn = 1990;
yearOfBorn = 1992;
console.log(yearOfBorn); // return errorدر مواردی که مطمئن هستیم مقدار متغیر ثابت می‌مونه، بهتره از const استفاده کنیم. برای مثال متغیر yearOfBorn برای هر فردی یه مقدار ثابت هست و تغیر نمی‌کنه.global scope:در مرورگر متغیرهایی که به وسیله‌ی var در global scope تعریف شده باشند، پراپرتی global object محسوب می‌شن:var message = &#039;hello world&#039;;console.log(window.message); // return &amp;quothello message&amp;quot.ولی این قانون برای let و const صدق نمی‌کنه و متغیرهایی که به وسیله این دو در global scope مرورگر که همون window object هست، پراپرتی global object محسوب نمی‌شن.function scope:یعنی اگر متغیری که به وسیله‌ی var تعریف می‌شه داخل یه فانکشن قرار گرفته باشه، فقط داخل اسکوپ اون فانکشن قابل دسترسی هست و خارج از اون نمی‌شه از اون متغیر استفاده کرد.function sayHello() {    
var message= &#039;Hello World!&#039;; 
 console.log(message); // return Hello World!  
 }  
 sayHello(); 
 console.log(message); // return message is not definedهمون طور که تو کد بالا دیدیم، متغیر message فقط داخل فانکشن قابل دسترس هست و خارج از اون تعریف نشده و « message is not defined» برگشت داده شده.در این مورد، let و const مشابه var عمل می‌کنن و فقط داخل اسکوپ فانکشن قابل دسترس هستند.function profile&#40;&#41; {
let name = &#039;jack&#039;;
const yearOfBorn = 1990;
let userName = name + yearOfBorn;
console.log(userName); // return jack1990
}
profile&#40;&#41;;
console.log(id); // return userName is not definedblock scope:بر خلاف let، var و const داخل بلاک اسکوپ قابل دسترس هستند. به محدوده‌ی بین { }، بلاک اسکوپ گفته می‌شه. پس let و const علاوه بر اینکه فانکشن اسکوپ بودن، بلاک اسکوپ هم هستن ولی var فقط فانکشن اسکوپ هست.{ 
var first = &#039;first message.&#039;; 
let second = &#039;second message&#039;; 
const third = &#039;third message&#039;; 
} 
console.log(first); // return &#039;first message&#039;. 
console.log(second); // return second is not defined 
console.log(third); // return third is not definedهمون طور که تو کد بالا می‌بینیم، متغیر first خارج از بلاک اسکوپ هم قابل دسترس هست ولی متغیرهای second و third قابل دسترس نیستن.* این نکته رو هم نباید فراموش کنیم که به صورت کلی از هیچ متغیری قبل از تعریف و مقداردهی، نمی‌تونیم استفاده کنیم. تفاوتی هم نمی‌کنه متغیر با استفاده از var تعریف شده باشه یا let و const.از این به بعد از var استفاده نکنیم؟کایل سیمپسون در این باره یه توصیه کرده. به این صورت که:از var برای متغیرهای top-level استفاده کنیم. متغیرهایی که تو چند اسکوپ‌های بزرگ به صورت همزمان استفاده می‌شه. مثلا متغیری که ممکنه تو چند ماژول استفاده بشه.از let برای تعریف متغیر در اسکوپ‌های کوچک‌تر استفاده کنیم. مثلا برای تعرف متغیر تو فانکشن‌های داخلی.بعد از اینکه پروژه تا حدودی جلو رفت و مطمئن شدیم متغیری که با let مقداردهی شده، مقدارش تا آخر ثابت می‌مونه، const رو جایگزین let کنیم. ( البته اگه ESLint استفاده کنین، به صورت اتوماتیک این کار براتون انجام می‌شه)   </description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Sun, 28 Mar 2021 14:24:54 +0430</pubDate>
            </item>
                    <item>
                <title>oop js- primitive &amp; reference</title>
                <link>https://virgool.io/@ehsan_n/oop-js-primitive-reference-ylnt5ar62zsk</link>
                <description>دیتا تایپ‌ها یکی از مباحث پایه‌ای و مهم جاوااسکریپت هستن که در مصاحبه‌های استخدامی معمولا یک سوال از این مبحث مطرح می‌شه. تو این پست درباره‌ی دیتا تایپ‌ها و از اون مهم‌تر تفاوت اون‌ها باهم، بحث می‌کنیم.در جاوااسکریپت یا هر زبان برنامه نویسی دیگه‌ای هر چیزی رو که بتونیم تو متغیر ذخیره کنیم، دیتا نامیده می‌شه. البته نوع دیتا با توجه به ماهیت‌شون، با هم تفاوت دارن.const name = &amp;quotMonica&amp;quot
const yearOfborn = 1964;
let isAlive = true;با توجه به کد بالا، متغیر name از نوع strring ، متغیر yearOfBorn از نوع number و متغیر isAlive از نوع boolean هستن.در جاوااسکریپت به صورت کلی 10 نوع دیتا تایپ داریم.این دیتا تایپ‌ها با توجه به ویژگی‌ها و رفتارشون به دو دسته تقسیم می‌شن: primitive typesreference typesPrimitive Types:برای اینکه با رفتار این دسته از دیتا تایپ‌ها آشنا بشیم، بهتره با یک مثال شروع کنیم.let x = 5;
let y = x;تو کد بالا ابتدا یک متغیر به نام x تعریف کردیم و مقدارش رو برابر با عدد 5 قرار دادیم. بعد یه متغیر دیگه به نام y تعریف کردیم و مقدارش رو برابر با مقدار متغیر x قرار دادیم. الان اگه مقدار متغیر x رو تغیر بدیم، به نظرتون مقدار متغیر y هم تغیر می‌کنه یا نه؟x = 10; 
console.log(y); // return 5با تغیر مقدار متغیر x به عدد 10، مقدار متغیر y هیچ تغیری نمی‌کنه و همون مقدار قبلی که عدد 5 بود، باقی می‌مونه. با نتایج بالا، مطمئنا این سوال براتون پیش میاد که چرا چنین اتفاقی افتاد؟ هنگامی که موتور جاوااسکریپت شروع به تفسیر کدمون می‌کنه، هر وقت به یه متغیر می‌رسه، مقدار اون متغیر رو چک می‌کنه؛ اگه مقدار متغیر، یکی از دیتا تایپ‌های primitive باشه، اون متغیر رو تو حافظه stack به عنوان یه متغیر مستقل ذخیره می‌کنه. بعد اینکه متغیر x که دیتایی از نوع primitive داره، تو حافظه stack ذخیره شد، نوبت به متغیر y می‌رسه.وقتی که موتور جاوااسکریپت به متغیر y رسید، مثل روال قبل، می‌ره سراغ مقدار متغیر y. اینجا مقدار متغیر y به صورت مستقیم نوشته نشده. ولی جلوش یه حرف x است. چون x داخل &quot; &quot; یا &#x27; &#x27; یا &#x60; &#x60; نیست، پس اون رو به عنوان مقدار string نمی‌خونه و پیش‌بینی می‌کنه که این حرف به عنوان متغیر تو حافظه stack ذخیره شده. بنابراین حافظه stack رو بررسی می‌کنه تا ببینه آیا متغیری به اسم x وجود داره یا نه. اگه وجود داشته باشه، مقدار اون متغیر رو برمی‌داره و به عنوان مقدار متغیر y قرار می‌ده. بعد از اینکه تکلیف مقدار متغیر y مشخص شد، موتور جاوااسکریپت اون رو با توجه به اینکه نوع مقدارش از نوع number و از دسته‌ی primitiveها است، داخل حافظه stack به عنوان متغیر مستقل ذخیره می‌کنه.اگه متغیری به اسم x رو قبلا تعریف نکرده بودیم و تو حافظه stack ذخیره نشده بود و موتور جاوااسکریپت مقداری برای متغیر y پیدا نمی‌کرد، به این نتیجه می‌رسید که مقداری برای متغیر y تعین نشده و undefined رو به عنوان مقدار اون در نظر می‌گرفت. همون طور که تو شکل بالا گفتیم، undefined هم یک دیتای primitive حساب می‌شه. پس با وجود اینکه در ابتدا مقداری برای متغیر y تعین نشده بود، چون در نهایت مقدار undefined به اون اختصاص داده شد و undefined هم یک دیتای primitive محسوب می‌شه، در نهایت متغیر y هم به عنوان یک متغیر مستقل در حافظه stack ذخیره می‌شد.بنابراین الان دو متغیر جدا و مستقل از هم به نام‌های x و y داریم که هیچ ارتباطی به هم ندارن و اگه مقدار متغیر x رو تغیر بدیم، مقدار متغیر y تغیری نمی‌کنه.حالا بهتره کمی درباره‌ی stack memory بدونیم.Stack Memory:حافظه stack نوعی از حافظه است که به سرعت قابل دسترسه. البته همون قدر که سریعه، محدود هم است. پس نمی‌تونه دیتای زیادی رو تو خودش ذخیره کنه. اگه بیش‌تر از ظرفیتش به اون دیتا وارد بشه، اصطلاحا گفته می‌شه: حافظه سرریز شد (stack over flow). به همین دلیل، این نوع حافظه مناسب دیتا تایپ‌های primitive است. چون برخلاف آرایه‌ها، آبجکت‌ها و فانکشن‌ها، primitiveها آنچنان حجم زیادی ندارن.دیتا تو حافظه stack به صورت منظم و بالای همدیگه قرار می‌گیرن.Reference Types:برای شناخت این نوع از دیتا تایپ‌ها با مثال مشابهی که برای دیتا تایپ‌های primitives استفاده کردیم، شروع می‌کنیم.let person = {
name: &amp;quotSteven&amp;quot,
yerOfBorn: 1946
};
let person2 = person;
person.name = &amp;quotChristopher&amp;quot
console.log(person2.name); // return Christopherاول یه آبجکت درست کردیم به اسم person که دو تا پراپرتی داره. بعد یه متغیر دیگه به اسم person2 ساختیم و مقدارش رو برابر با person قرار دادیم. بعد مقدار پراپرتی‌ name آبجکت person رو تغیر دادیم.در آخر وقتی مقدار پراپرتی name آبجکت person2 رو چک کردیم، متوجه شدیم مقدار پراپرتی name این آبجکت هم تغیر کرده. یعنی رفتار refrences کاملا برعکس رفتار primitives است. ولی سوالی که حتما باز هم به ذهن‌‌تون میاد اینکه، چرا؟ چرا باید همچین رفتاری داشته باشن؟همون طور که قبلا هم گفته شد، موقع تفسیر کدهای جاوااسکریپت، هر وقت موتور جاوااسکریپت به یک متغیر می‌رسه، مقدار اون متغیر چک می‌شه که آیا از نوع primitive است یا reference. در مثال قبل حالتی که نوع دیتا، primitive باشه رو بررسی کردیم. وقتی دیتای ذخیره شده در متغیر از نوع reference باشه، موتور جاوااسکریپت ابتدا خود متغیر رو در حافظه‌ stack ذخیره می‌کنه ولی مقدارش رو ذخیره نمی‌کنه. چون گفتیم حافظه stack محدوده و به دلیل اینکه دیتاهای reference حافظه‌ی زیادی رو اشغال می‌کنن، باید اون‌ها رو در یک حافظه دیگه ذخیره کنه و اون حافظه، heap نام داره. بنابراین به جای اینکه مقدار اون متغیر رو تو stack ذخیره کنه، یک آدرس رو به عنوان مقدار به اون می‌ده که حافظه کمتری رو اشغال می‌کنه (برای درک بهتر موضوع، فرض کنیم اون آدرس یه آیدی عددی است). از این به بعد متغیری که در حافظه stack ذخیره شده به عنوان pointer شناخته می‌شه. چون به جای اینکه مقدار متغیر رو تو خودش ذخیره کنه، یه آدرسی رو ذخیره کرده که به جای اصلی مقدار متغیر در حافظه heap اشاره می‌کنه.الان متغیر person یه pointer تو حافظه stack داره که اون pointer یه آدرس رو به عنوان مقدار داره و اون آدرس به جایی در حافظه heap اشاره می‌کنه که مقدار اصلی متغیر person اونجا ذخیره شده.وقتی نوبت به متغیر person2 می‌رسه، باز هم موتور جاوااسکریپت متوجه می‌شه مقداری به صورت مستقیم به متغیر person2 داده نشده و جلوش مقدار person نوشته شده که چون داخل &quot; &quot; یا &#x27; &#x27; یا &#x60; &#x60; نیست، string هم حساب نمی‌شه. موتور جاوااسکریپت حدس می‌زنه preson، یک متغیر در حافظه stack باشه. پس حافظه stack رو بررسی و متغیر person رو پیدا می‌کنه و مقدار اون متغیر رو برمی‌داره تا به عنوان مقدار متغیر person2 قرار بده. نکته‌ای که تو این قسمت باید به اون توجه کنیم اینه که چیزی که به عنوان مقدار متغیر person در حافظه stack ذخیره شده، همون آدرسی است که قبلا درباره‌ی اون صحبت کردیم. پس درواقع موتور جاوااسکریپت آدرس رو به عنوان مقدار متغیر person برمی‌داره و به عنوان مقدار متغیر person2 قرار می‌ده و به این ترتیب هر دو متغیر دارای یک آدرس مشترک می‌شن. یعنی مقادیر دو متغیر person و person2 یک جا ذخیره شدن.پس اگه مقدار متغیر person رو تغیر بدیم، مقدار متغیر person2 هم تغیر می‌کنه. این بار نوبت حافظه heap است که کمی بررسی کنیم اون رو.Heap Memory:حافظه heap دقیقا برعکس حافظه stack است. یعنی این حافظه کنده و طول می‌کشه تا اطلاعات اون رو خوند. این حافظه اطلاعات بیشتری رو می‌تونه تو خودش ذخیره کنه و به همین دلیل، دیتاهای reference تو این حافظه ذخیره می‌شن. دیتا تو حافظه heap به صورت نامنظم و رندم ذخیره می‌شن و هر دیتا برای خودش یه آدرس داره.const athlete = {
name: &amp;quotRoger&amp;quot,
yearOfBorn: 1981
};

const actor = {
name: &amp;quotMorgan&amp;quot,
yearOfBorn: 1937
};

const musician = {
name: &amp;quotFrédéric&amp;quot,
yearOfBorn: 1810
};</description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Thu, 13 Feb 2020 13:05:14 +0330</pubDate>
            </item>
                    <item>
                <title>oop js- function constructor</title>
                <link>https://virgool.io/@ehsan_n/oop-js-function-constructor-elbak8qmguib</link>
                <description>برنامه‌نویسی شیءگرا یک روش برنامه نویسی است که در نگاه اول شاید یک مبحث سخت و پیچیده به نظر برسه ولی اگه مباحث پایه‌ای برنامه‌نویسی شیءگرا رو بلد باشیم، این روش خیلی ساده می‌شه برامون و می‌تونیم از اون در ساخت برنامه‌هامون استفاده. با جاوااسکریپت هم می‌تونیم به صورت شیءگرا برنامه نویسی کنیم. به شرطی که مباحث ساده‌ی پایه‌ای رو به درستی درک کنیم. یکی از اون مباحث پایه‌ای، مفهوم «function constructor» است که تو این پست قراره درباه‌ش بحث کنیم.قبل از هر چیزی بهتره اول از خود آبجکت‌ها شروع کنیم. وقتی یه سری اطلاعات مرتبط به هم رو داریم، بهترین راه برای ذخیره کردن اون‌ها، استفاده از آبجکته. برای مثال ما یه سری از اطلاعات شخصی (نام و سال تولد) یه بازیگر سینمایی رو داریم و می‌خواهیم اون‌ها رو تو یه آبجکت ذخیره کنیم. همون طور که می‌دونین آبجکت در جاوااسکریپت به صورت زیر تعریف می‌شه.const actor = {
fullName: &amp;quotLeonardo DiCaprio&amp;quot,
yearOfBorn: 1974,
calcAge() {
let date, currentYear;
date = new Date();
currentYear = date.getFullYear();
return currentYear - this.yearOfBorn;
}
};تو این آبجکت ساده، نام و سال تولد بازیگر ذخیره شده. همچنین این آبجکت یه متد هم داره که سن بازیگر رو  با استفاده از سال تولدش محاسبه می‌کنه.حالا اگه قصد داشته باشیم اطلاعات یه بازیگر دیگه‌ رو تو یه آبجکت ذخیره کنیم، چه کار باید بکنیم؟خب معلومه، یه آبجکت دیگه به اسم actor2 درست می‌کنیم. برای اینکه تو زمان هم صرفه‌جویی کنیم، آبجکت اول رو کپی و بعد پیست می‌کنیم و فقط نام و سن اون رو تغیر می‌دیم و با خودمون فکر می‌کنیم چقدر خفنیم ما!const actor2 = {
fullName: &amp;quotTom Hanks&amp;quot,
yearOfBorn: 1956,
calcAge() {
let date, currentYear;
date = new Date();
currentYear = date.getFullYear();
return currentYear - this.yearOfBorn;
}
};ولی اگه نیاز داشته باشیم اطلاعات سه بازیگر رو ذخیره کنیم چی؟ قبل از اینکه درباره‌ی جواب سوال بالا فکر کنیم، این نکته رو گوشه‌ی ذهن‌مون داشته باشیم که شاید لازم باشه اطلاعات 1000 بازیگر رو به صورت آبجکت ذخیره کنیم. با فکر کردن به این نکته، نتیجه‌ می‌گیریم که روش کپی پیست کردن آبجکت‌ها آنچنان هم عاقلانه نیست. چون برنامه نویسی یعنی انجام کار کمتر با حذف کارهای تکراری. درضمن باید به این نکته هم توجه کنیم که در مثال فعلی با آبجکت‌هایی که فقط یک متد چند خطی که برای محاسبه‌ی سن بازیگر کاربرد دارن سروکار داریم. اگه در شرایطی قرار بگیریم که هر آبجکت چندین متد چند صد خطی داشته باشه، با کپی پیست آبجکت‌ها، چند صد خط تکراری به برنامه‌ی خودمون اضافه می‌کنیم که حجم کدمون رو زیاد و حافظه‌ی دستگاه رو اشغال می‌کنن.درست در همین لحظه است که «function constructor»  یا «تابع سازنده» در مقام یک قهرمان وارد بازی می‌شه و کاری می‌کنه که ما باز هم احساس خفن بودن بکنیم!وقتی که ناامیدانه نشستیم و منتظریم قهوه‌مون سرد بشه، تابع سازنده مثل یه دوست قدیمی میاد و می‌زنه رو شونه‌مون و میگه: «آخه دختر/ پسر خوب اگه یکم بیشتر دقت کنی‌ می‌بینی که همه‌ی آبجکت‌ها تو ویژگی‌هاشون مشترکن و چیزی که اون‌ها رو متمایز می‌کنه، مقدار ویژگی‌هاشونه. هر دو آبجکت قبلی پراپرتی‌های fullName و yearOfBorn رو دارن ولی مقدراشون با هم فرق می‌کنه.»پس برای برای ساخت یه آبجکت، به جای اینکه کلا اونا رو از اول بنویسیم، یه قالب اولیه (prototype) با کمک تابع سازنده درست می‌کنیم و بعد از اون فقط مقادیر رو عوض می‌کنیم تا یه آبجکت جدید ساخته بشه. (دقیقا مثل قالب کیک)تابع سازنده چیزی نیست جز یه فانکشن ساده که قراره قالب اولیه‌ی (prototype) آبجکت‌هایی باشه که از این به بعد بسازیم:function Actor (){
};برای اینکه تابع سازنده از فانکشن‌های دیگه متمایز باشه، حرف اول اون رو به صورت بزرگ می‌نویسیم.با توجه به مثال قبلی آبجکت‌هایی که قراره ساخته بشن فقط دو تا ویژگی به عنوان اطلاعات اولیه دارن؛ یکی اسم‌شون (fullName) و اون یکی تاریخ تولدشون (yearOfBorn). پس فقط دو تا پارامتر ورودی به تابع سازنده اضافه می‌کنیم.function Actor (fullName, yearOfBorn){
 };در قدم بعدی از  this keyword استفاده می‌کنیم. اگه دوست دارین درباره‌ی this بیشتر بدونین، پست زیر رو حتما بخونین. http://vrgl.ir/mtTXV با کمک ‌this می‌تونیم مقادیر مختلفی رو به هر یک از آبجکت‌هایی که قراره از روی نمونه‌ی اولیه (prototype) یا همون تابع سازنده خودمون ساخته بشن، اعمال کنیم.function Actor(fullName, yearOfBorn) {
this.fullName = fullName;
this.yearOfBorn = yearOfBorn;
this.calcAge = function (){
let date, currentYear;
date = new Date();
currentYear = date.getFullYear();
return currentYear - this.yearOfBorn;
}
};برای آخرین مرحله از ساخت آبجکت به وسیله تابع سازنده، فقط کافیه با استفاده از new keyword تابع سازنده رو به همراه آرگومان‌های ورودی فراخوانی و اون رو تو یه متغیر ذخیره کنیم.const leonardo = new Actor(&amp;quotLeonardo DiCaprio&amp;quot, 1974);تو این مرحله new keyword سه کار انجام می‌ده:1- یک آبجکت جدید و خالی({}) می‌سازه.2- دومین کاری که می‌کنه اینکه با استفاده از فانکشن فراخوانی شده‌ی بعد خودش، thisها رو بر روی آبجکت جدیدی که در مرحله‌ی اول ساخته، ست می‌کنه.مقدار آرگومان اول تابع Actor برابره با «Leonardo DiCaprio». این مقدار به عنوان اولین پارامتر ورودی (fullName) به تابع سازنده پاس داده می‌ده و داخل تابع، this.fullName برابر با مقدار اولین پارامتر ورودی (Leonardo DiCaprio) می‌شه. یعنی this.fullName بعد از ست شدن، به عنوان یکی از ویژگی‌های (پراپرتی) آبجکت جدید به حساب میاد و مقداری هم که جلوی this.fullName قرار گرفته، مقدار اون ویژگی قرار می‌گیره. همچنین این روال برای متغیرها و فانکشن‌های دیگه هم تکرار می‌شه و به این ترتیب this.fullName و this.yearOfBorn به عنوان پراپرتی‌ها و this.calcAge هم به عنوان متد آبجکت جدید به حساب میان.3- آبجکت جدیدی رو که ساخته و پراپرتی‌ها و متدها رو براشون اعمال کرده، برگشت (return) می‌ده.بعد اینکه new کارش رو تموم کرد، مقدار برگشت داده شده داخل متغیر leonardo ذخیره می‌کنیم تا هر وقت خواستیم از اون استفاده کنیم.البته برای محاسبه‌ی سن هر آبجکت باید متد اون رو فراخوانی کنیم.let leonardoAge = leonardo.calcAge()
console.log(leonardoAge);الان می‌تونیم به راحتی آبجکت‌های جدید دیگه‌ای رو بدون کپی کردن قسمت‌های تکراری کدمون درست کنیم.Const tom = new Person(&amp;quotTom Hanks&amp;quot, 1956);
const ralph = new Actor(&amp;quotRalph Fiennes&amp;quot, 1962);
Const johnny = new Person(&amp;quotJohnny Depp&amp;quot, 1963);
Const brad = new Person(&amp;quotBrad Pitt&amp;quot, 1963);
Const cillian = new Person(&amp;quotCillian Murphy&amp;quot, 1976);در جاوااسکریپت هر آبجکت چندین پراپرتی و متد پیش‌فرض داره. constructor یکی از اون پراپرتی‌ها است. این پراپرتی، تابع سازنده‌ی آبجکت رو مشخص می‌کنه.function Actor(fullName, yearOfBorn) { 
this.fullName = fullName; 
this.yearOfBorn = yearOfBorn; 
this.calcAge = function() { 
let date, currentYear; 
date = new Date(); 
currentYear = date.getFullYear(); 
return currentYear - this.yearOfBorn; } 
};
const leonardo = new Actor(&amp;quotLeonardo DiCaprio&amp;quot, 1974);
console.log(ralph.constructor); // return Actor()

const ralph = new Actor(&amp;quotRalph Fiennes&amp;quot, 1962); 
console.log(ralph.constructor); // return Actor()

Const tom = new Person(&amp;quotTom Hanks&amp;quot, 1956);
console.log(tom.constructor); // return Actor()همون طور که می‌بینیم، obj.constructor برای همه‌ی آبجکت‌هایی که از روی تابع سازنده Actor ساخته شدن، مقدار ()Actor رو برگشت می‌ده.بیاین بحث‌مون رو با یه مثال ساده‌ی دیگه ادامه بدیم. این بار قصد داریم اطلاعات یه ورزشکار رو در قالب آبجکت ذخیره کنیم. البته این بار، آبجکت رو با همون روش اولیه ایجاد می‌کنیم و نیازی به تابع سازنده نیست.const athlete= {
fullName: &amp;quotRoger Federer&amp;quot,
yearOfBorn: 1981
};با پراپرتی constructor که چند خط بالاتر آشنا شدیم. الان قصد داریم دوباره از این پراپرتی استفاده کنیم و از کنسول مرورگر کروم کمک بگیریم تا ببینیم که آیا این آبجکتی که با روش معمول درست کردیم، تابع سازنده یا نمونه‌ی اولیه داره یا نه؟const athlete= { fullName: &amp;quotRoger Federer&amp;quot, yearOfBorn: 1981 };
athlete.constructor // return Object()همون طور که می‌بینیم یه فانکشن به عنوان تابع سازنده (prototype) آبجکت athlete برگشت داده شده. ولی ما هیچ تابع سازنده‌ای به اسم Object تو کدی که نوشته بودیم، نداشتیم. پس اون از کجا اومده؟ اگه دقت کنین، توی اون تابع سازنده نوشته شده: «native code». یعنی ()Object به صورت خودکار در ساختار زبان جاوااسکریپت وجود داره. یعنی وقتی که ما آبجکت Athlete رو به شکل {} = obj تعریف می‌کنیم، موتور جاوااسکریپت موقع خوندن کدمون اون رو به صورت زیر تغیر می‌ده تا قابل تفسیر باشه:const athlete = new Object({ fullName: &amp;quotRoger Federer&amp;quot, yearOfBorn: 1981 });پس وقتی در ظاهر یک آبجکت رو به سادگی به صورت {} = obj تعریف می‌کنیم در باطن به صورت کد بالا تفسیر می‌شه.اگه بعد از تعریف athlete تو کنسول مرورگر، athlete رو بنویسیم و دکمه‌ی اینتر رو فشار بدیم، اون پایین، Object رو به عنوان نمونه‌ی اولیه‌ی آبجکت athlete معرفی می‌کنه.البته توابع سازنده‌ای که در ساختار جاوااسکریپت وجود دارن، محدود به ()Object نیست.برای مثال یه متغیر به صورت string تعرف ‌می‌کنیم.const language = &amp;quotjavascript&amp;quot پراپرتی constructor رو علاوه بر آبجکت‌ها، برای دیتا تایپ‌های دیگه هم می‌تونیم به‌کار ببریم. پس بیاین امتحان کنیم تا ببینیم به چی می‌رسیم.const language = &amp;quotjavascript&amp;quot
language.constructor;این بار برای متغیر language یه تابع سازنده به نام ()String برگشت داده. پس مثل آبجکت‌، string هم با استفاده از یه تابع سازنده‌ی نیتیو ساخته می‌شه. درواقع کد بالا هنگام تفسیر به شکل زیر تغیر می‌کنه.const language = new String(&amp;quotjavascript&amp;quot);البته دیتا تایپ‌های از نوع array ،boolean ،number و function هم با این روش ساخته می‌شن و هر کدوم از این متغیرها، به صورت پیش‌فرض توابع سازنده‌ی خودشون رو دارن.const number = 1; // const number = new Number(1);
const arrNums = [1, 2, 3]; // const arrNums = new Array([1, 2, 3]);
const isAlive = true; // const isAlive = new Boolean(true);
const sayHello = function(message) {console.log(message);};  //const sayHello = new Function(&amp;quotmessage&amp;quot, &amp;quotconsole.log(message);&amp;quot);پس تا اینجا فهمیدیم که علاوه بر آبجکت‌ها، دیتا تایپ‌های ذکر شده هم برای خودشون توابع سازنده‌ی مخصوصی دارن.حالا دیگه وقتش رسیده قدم آخر رو برداریم تا با یک واقعیت روبه رو بشیم. اون واقعیت هم یک جمله است که گفته می‌شه: «همه چی تو جاوااسکریپت یه آبجکته».این بار قراره یه آرایه‌ی خالی بسازیم.const arr = [];متغیر arr رو تو کنسول مرورگر می‌نویسیم تا تابع سازنده‌ی اون رو پیدا کنیم.در مرحله‌ی اول به تابع سازنده‌ی ()Array می‌رسیم که قبلا درباره‌ی اون بحث کردیم. اگه روی ()Array کلیک کنیم، یه سری پراپرتی و متد می‌بینیم که مخصوص آرایه‌ها هستن. اگه اسکرول بکنیم و به پایین اون لیست برسیم، می‌بینیم که ()Object رو به عنوان تابع سازنده‌ی ()Array معرفی کرده. یعنی خود ()Array که به عنوان تابع سازنده‌ی آرایه‌ها شناخته می‌شه از یک تابع سازنده‌ی دیگه به اسم ()Object ساخته شده.بقیه‌ی توابع سازنده هم مثل ()Array، از یک تابع سازنده‌ی بزرگ‌تر به اسم ()Object ساخته شدن که معمولا در اصطلاح به‌ اون آبجکت ریشه (root Object) گفته می‌شه.پس عکس قبلی رو بهتره به صورت زیر تغیر بدیم.چون همه‌ی توابع سازنده در نهایت به root Object ختم می‌شن، به همین دلیله که گفته می‌شه: «همه چی در جاوااسکریپت یه آبجکته.»و ما الان دلیل این جمله رو می‌دونیم. الان فقط یه نکته مونده که اون رو هم بررسی می‌کنیم و بحث‌مون تموم می‌شه.برگردیم به آبجکت‌هایی که حاوی اطلاعات بازیگران بودن. یه آبجکتی داشتیم که تو متغیر leonardo ذخیره شده بود. اون آبجکت به کمک یه تابع سازنده به اسم ()Actor ساخته شده بود. قبلا گفتیم که تابع سازنده‌ای که ساختیم فقط یه فانکشن ساده است. این نکته رو هم گفتیم که فانکشن‌ها با استفاده از تابع سازنده‌ی پیش‌فرض ()Function که در ساختار زبان جاوااسکریپت وجود داره، ساخته می‌شن و خود اون تابع سازنده با کمک root Object ساخته می‌شه. پس وقتی آبجکت leonardo رو می‌سازیم به ترتیب عکس زیر یه سری کارها انجام می‌شه.آبجکت ریشه و تابع سازنده‌ی ()Function که به صورت پیش‌فرض وجود دارن. تابع سازنده‌ی ()Actor با کمک نمونه‌ی اولیه‌ی خودش که تابع سازنده‌ی ()Function است ساخته می‌شه و آبجکت leonardo از روی تابع سازنده‌ی ()Actor ساخته می‌شه.پس دو نوع تابع سازنده داریم: 1- توابع سازنده‌ی پیش‌فرض جاوااسکریپت. (مثل ()Function و ()Array و ...)2- توابع سازنده‌ای که خودمون می‌تونیم درست کنیم. (مثل ()Actor)</description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Fri, 07 Feb 2020 18:07:30 +0330</pubDate>
            </item>
                    <item>
                <title>پشت‌پرده جاوااسکریپت- بخش 3</title>
                <link>https://virgool.io/@ehsan_n/%D9%BE%D8%B4%D8%AA%D9%BE%D8%B1%D8%AF%D9%87-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A8%D8%AE%D8%B4-3-tagdgkqi0pjm</link>
                <description>تو بخش اول و دوم مقاله به ترتیب درباره execution context و دو تا از پراپرتی‌هاش صحبت کردیم و قرار شد تو بخش سوم درباره پراپرتی سوم که this هست بحث کنیم تا برسیم به چگونگی ایجاد execution context.وقتی execution context ساخته می‌شه this هم مثل scope chain و variable object باهاش همراه و تو execution context ذخیره می‍شه تا مثل اون دو تا یه سری امکانات در اختیار ما قرار بده.this keyword:به صورت خلاصه this به یک object اشاره داره. به عبارت بهتر this به آبجکتی اشاره داره که فانکشن در حال اجرای فعلی رو اجرا (execute) می‌کنه. (به فارسی سخت!) یکی از مزیت‌های this این هست که می‌تونیم با استفاده از اون، فانکشن‌ها رو با مقادیر مختلف قابل استفاده کنیم. یعنی یه فانکشن بنویسیم و در موقعیت‌های مختلف اون فانکشن رو با مقادیر مختلف استفاده کنیم و این کار باعث می‌شه هم در کد و هم در حافظه برنامه صرفه‌جویی کنیم.اگه یادتون باشه تو بخش اول گفتیم که:می‌شه execution context رو به عنوان یک شئ (object) در نظر گرفت.و همین‌طور گفته شد:اگر execution context رو به عنوان object درنظر بگیریم، global execution context هم به عنوان global object شناخته می‌شه.با توجه به تعریفی که از this نوشتیم و این دو یادآوری، this درواقع به یک execution context اشاره داره.پس در موقعیت‌های مختلف، this به آبجکت‌ها و execution context های مختلفی اشاره می‌کنه:1- this &amp; Window (window binding):console.log(this); // return window objectاگه this رو در global scope استفاده کنیم، به global execution context یا همون global object اشاره داره. اگه بخش اول مقاله یادتون باشه، گفتیم که:در مرورگر، window object همون global object هست.2- this &amp; regular Function (Implicit binding):var name = &#039;Milan&#039;;
function footballClub () {
var name = &#039;Arsenal&#039;;
console.log(this); // return window object
console.log(this.name); // return Milan
}
footballClub();وقتی this داخل یه فانکشن نوشته می‌شه به global execution context یا همون global object اشاره داره!به همین دلیل this موجود در فانکشن ()footballClub به gloabl object اشاره می‌کنه و this.name داخل فانکشن به name موجود در global object.3- this &amp; Method (Implicit binding):var name = &#039;Milan&#039;;
var footballClub = {
name : &#039;Arsenal&#039;,
clubDetail : function () {
console.log(this); // return footballClub object 
console.log(this.name); // return Arsenal
}
}
footballClub.clubDetail(); برخلاف فانکشن‌ها وقتی this داخل یه متد بکار می‌ره، اشارش به اون آبجکتی هست که داخلش تعریف شده و (آبجکت) اون method رو فراخوانی می‌کنه.اشاره this به آبجکت footballClub هست. چون this داخل متدی که تو این آبجکت به‌کار رفته، استفاده شده. this.name هم به name موجود در footballClub object اشاره می‌کنه نه name موجود در global object.* یه نکته که باید به اون توجه داشته باشیم اینه که اگه یه فانکشن داخل یه متدی بکار رفته باشه، this موجود در اون فانکش باز هم به global object اشاره خواهد داشت.4- this &amp; new (new binding):function Person (fullName, yearOfBirth, job) {
this.fullName = fullName;
this.yearOfBirth = yearOfBirth;
this.job = job;
console.log(this) // retun Elon object and Jeffrey object
}
var Elon = new Person(&#039;Elon Reeve Musk&#039;, 1971, &#039;CEO&#039;);
var Jeffrey = new Person(&#039;Jeffrey Preston Bezos&#039;, 1964, &#039;CEO&#039;);در جاوااسکریپت یکی از راه‌های ساخت object، استفاده از function constructor هست. تو این روش ابتدا یه فانکشن به عنوان نمونه اولیه ایجاد می‌شه و بعدا آبجکت‌ها به عنوان نمونه‌‌های کپی شده از این function constructor ساخته می‌شن.خب بیاین کد بالا رو یکم دقیق‌تر بررسی کنیم:1- در مرحله اول فانکشن ()Person رو که یه function constructor هست رو می‌سازیم که 3 پارامتر داره و به عنوان نمونه اولیه از آبجکت‌هایی که بعدا از روی اون ساخته می‌شن شناخته می‌شه.2- تو این مرحله با استفاده از new و فانکشن ()Person، آبجکت Elon رو به وجود میاریم. به این صورت که:ابتدا new یک آبجکت خالی رو می‌سازه. بعد از new، فانکشن ()Person فراخوانی می‌شه که 3 پارامتر هم داره. پس آبجکت جدید (با استفاده از پارامترهای وارد شده) ساخته و در داخل متغیر Elon ذخیره می‌شه.3- در این مرحله هم آبجکت Jeffrey مثل مرحله قبل ساخته می‌شه. کاری که new در این موقعیت انجام می‌ده درواقع اینه که اشاره this رو از window object (چون اینجا this داخل یه فانکشن بکار رفته) به آبجکتی که تازه ساخته شده (Elon و Jeffrey) منتقل کنه. یعنی اگه کد بالا رو به صورت زیر که بدون بکار بردن new هست بنویسیم، this به window object اشاره می‌کنه:function Person (fullName, yearOfBirth, job) { 
this.fullName = fullName; 
this.yearOfBirth = yearOfBirth; 
this.job = job; console.log(this) // return Window object twice 
} 
var Elon = Person(&#039;Elon Reeve Musk&#039;, 1971, &#039;CEO&#039;); 
var Jeffrey = Person(&#039;Jeffrey Preston Bezos&#039;, 1964, &#039;CEO&#039;);5- call(), apply() and bind() (Explicit binding):call():var name = &#039;Adam Wathan&#039;;
var job = &#039;back-end developer&#039;;
var developer = function () {
console.log(&#039;My name is &#039; + this.name + &#039;, I am &#039; + this.job);
}
var rachel = {
name: &#039;Rachel Andrew&#039;,
job: &#039;front-end developer&#039;
}
developer(); // return &amp;quotMy name is Adam Wathan, I am back-end developer&amp;quot
developer.call(rachel); // return &amp;quotMy name is Rachel Andrew, I am front-end developer&amp;quotدر مثال بالا یه فانکشن داریم به اسم ()developer. بار اولی که این فانکشن فراخوانی شده (خط 10)، مقدار «My name is Adam Wathan, I am back-end developer» برگشت داده می‌شه. چون this داخل یه فانکشن بکار رفته و به همین دلیل شاره اون به window object هست.ولی بار دومی که این فانکشن فراخوانی شده همراه با متد ()call بوده. تو این مثال متد ()call همون نقش new رو در مثال قبلی بازی می‌کنه. یعنی اشاره this رو از window object برمی‌داره و به آبجکتی که ما می‌خایم (آبجکت rachel) منتقل می‌کنه. و این بار مقدار «My name is Rachel Andrew, I am front-end developer» برگشت داده می‌شه.شاید سوال پیش بیاد که چرا اینجوری کد رو نوشتیم و چرا از همون اول فانکشن ()developer رو به عنوان متد داخل خود آبجکت بکار نبردیم؟فرض کنین به جای یک آبجکت در مثال بالا، هزار آبجکت داشتیم و فانکشن ()developer هم به جای اینکه یک خط بود، هزار خط کد داشت. اگر می‌خاستیم این فانکشن هزار خطی رو به عنوان متد به هر یک از این هزار آبجکت اضافه کنیم، حافظه برنامه خیلی زود پر می‌شد و یا برنامه با کندی عمل می‌کرد. ولی با استفاده از متد ()call هر هزار آبجکت می‌تونن از این فانکشن بدون اشغال بیش از حد حافظه استفاده کنن. یه نکته که باید در مورد متد call بدونیم این هست که می‌تونیم بیش از یک آرگومان به این متد وارد کنیم.var developer = function (skill1, skill2, skill3) {
console.log(&#039;My name is &#039; + this.name + &#039;, I am &#039; + this.job + &#039;. I know &#039; + skill1 + &#039;, &#039; + skill2 + &#039;, &#039; + skill3);
}
var rachel = {
name: &#039;Rachel Andrew&#039;,
job: &#039;front-end developer&#039;
}
developer.call(rachel, &#039;HTML&#039;, &#039;CSS&#039;, &#039;Javascript&#039;); // return &amp;quotMy name is Rachel Andrew, I am front-end developer. I know HTML, CSS, Javascript&amp;quotapply():عملکرد متد ()aplly مشابه متد ()call هست، با این تفاوت که به این متد فقط دو آرگومان می‌تونیم وارد کنیم که آرگومان دوم باید به صورت آرایه باشه.var developer = function (skill1, skill2, skill3) {
console.log(&#039;My name is &#039; + this.name + &#039;, I am &#039; + this.job + &#039;. I know &#039; + skill1 + &#039;, &#039; + skill2 + &#039;, &#039; + skill3);
}
var rachel = {
name: &#039;Rachel Andrew&#039;,
job: &#039;front-end developer&#039;
}
var skills = [&#039;HTML&#039;, &#039;CSS&#039;, &#039;Javascript&#039;];
developer.apply(rachel, skills); &amp;quotMy name is Rachel Andrew, I am front-end developer. I know HTML, CSS, Javascript&amp;quotهمون طور که می‌بینید، عملکرد این متد شبیه متد ()call هست و دقیقا همون مقدار رو برگشت داده. فقط به جای اینکه «HTML»، «CSS» و «Javascript» رو به صورت آرگومان‌های جدا به متد اضافه کنیم، اون‌ها رو تو یه آرایه ذخیره و اون آرایه رو به عنوان آرگومان دوم به متد وارد کردیم.bind():متد ()bind هم با کمی تفاوت مثل متد ()call عمل می‌کنه:var developer = function (skill1, skill2, skill3) {
console.log(&#039;My name is &#039; + this.name + &#039;, I am &#039; + this.job + &#039;. I know &#039; + skill1 + &#039;, &#039; + skill2 + &#039;, &#039; + skill3);
}
var rachel = {
name: &#039;Rachel Andrew&#039;,
job: &#039;front-end developer&#039;
}
var developerRachel = developer.bind(rachel, &#039;HTML&#039;, &#039;CSS&#039;, &#039;Javascript&#039;);
developerRachel(); // return &amp;quotMy name is Rachel Andrew, I am front-end developer. I know HTML, CSS, Javascript&amp;quotتفاوت متد ()bind در این هست که بلافاصله فانکشن مورد نظر (فانکشن ()developer) رو فراخوانی و اجرا نمی‌کنه، بلکه یک نمونه کپی شده از اون تابع رو تولید می‌کنه و برگشت می‌ده و ما می‌تونیم با ذخیره اون در یک متغیر (متغیر developerRachel) در مواقع نیاز، اون فانکشن رو فراخوانی و اجرا کنیم.تا اینجا درباره‌ی سه ویژگی execution context بحث کردیم و الان هر سه ویژگی رو به صورت کامل می‌شناسیم.از این به بعد درباره‌ی چگونگی ساخته شدن execution context بحث می‌کنیم.موتور جاوااسکریپت execution context رو در دو مرحله ساخته و اجرا می‌کنه:قبل از اجرای کد، یک مرحله داریم به اسم creation phase.1- creation phase:تو اولین قدم از این مرحله، variable object ساخته می‌شه. به این صورت که:در صورتی که سازنده‌ی execution context یک فانکشن باشه، ابتدا آرگومان‌های فانکشن (در صورت وجود) داخل argument object ذخیره می‌شه (خود argument object بعد از ساخته شدن VO، داخل اون ذخیره می‌شه).بعد موتور جاوااسکریپت، داخل کدها جست و جو می‌کنه تا جایی که فانکشن‌ فراخوانی شده رو پیدا کنه. بعد از اینکه فراخوانی تابع پیدا شد، VO مختص به اون فانکشن ساخته و اطلاعات اون فانکشن داخل VO ذخیره می‌شه. پس تمام فانکشن‌ها قبل از اجرای کد، داخل VO و در نتیجه execution context خودشون ذخیره می‌شن.بعد اینکه تکلیف فانکشن‌های فراخوانی شده‌ی کد روشن شد، نوبت به متغیرهایی می‌رسه که فراخوانی شدن. در این مرحله متغیرهایی که فراخوانی شدن داخل VO ذخیره می‌شن و مقدارشون برابر با undefined قرار داده می‌شه. متغیر حتی اگه مقداردهی هم شده باشه، تو این مرحله مقدارش برابر با undefined هست.با توجه به گفته‌های دو پاراگراف آخر، چون فانکشن‌ها (declaration functions) و متغیرها در مرحله‌ی creation در VO ذخیره می‌شن، قبل از اجرای کد قابل دسترس هستند و در اصطلاح گفته می‌شه که hoisted شدن و به این عمل hoisting گفته می‌شه.به همین دلیل هست که ما می‌تونیم از declaration functions قبل از فراخوانی و از متغیرها قبل از مقداردهی استفاده کنیم. هر چند در صورت اینکه اگر از متغیرها قبل مقداردهی استفاده کنیم، مقدار برگشتی برابر با undefined خواهد بود.در دومین قدم scope chain اون execution context ساخته می‌شه.و در سومین قدم مشخص می‌شه که this اون execution context به چه آبجکتی اشاره می‌کنه.2- execution phase:در دومین مرحله، کدهای execution contextهای execution stack به صورت خط به خط اجرا می‌شن و بعد از اینکه همه‌ی کدهای یک execution context اجرا شد، اون execution context از execution stack حذف می‌شه.</description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Fri, 06 Dec 2019 10:29:09 +0330</pubDate>
            </item>
                    <item>
                <title>پشت‌ پرده جاوااسکریپت- بخش 2</title>
                <link>https://virgool.io/@ehsan_n/%D9%BE%D8%B4%D8%AA-%D9%BE%D8%B1%D8%AF%D9%87-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A8%D8%AE%D8%B4-2-nsniznjvoqnn</link>
                <description>تو بخش اول مقاله درباره‌ execution context, global execution context و execution stack بحث کردیم. اگه یادتون باشه تو بخش اول مقاله گفتیم که:می‌شه execution context رو به عنوان یک شئ (object) هم در نظر گرفت که ویژگی‌هایی (properties) هم داره.خب، وقتشه execution context رو بیشتر بررسی کنیم و ببینیم  execution context چجوری به وسیله‌ی موتور جاوااسکریپت ساخته می‌شه.در جاوااسکریپت execution context یک مفهوم انتزاعی و فرضی است که اطلاعات (this keyword, objects variables, functions) قسمتی از کد که در حال تفسیر و اجرا توسط موتور جاوااسکریپت (javascript engine) است در آن ذخیره شده. به عبارت بهتر هر زمانی که کد در جاوااسکریپت اجرا می‌شه در واقع داخل یک execution context این اتفاق می‌افته.**نکته مهم** در ورژن ES6 جاوااسکریپت، پراپرتی‌های execution context بر اساس دو مفهوم VariableEnvironment و LexicalEnvironment ارائه شدن. هر چند مفهوم کلی چندان تفاوتی نکرده. برای کسانی که می‌خان با این مفاهیم آشنا بشن، به نظرم اگه ابتدا با مفاهیم قدیمی‌تر شروع کنن بهتره و کمتر سردرگم می‌شن.Execution Context Object Properties:1- variable object:یک مفهوم انتزاعی که تمام اطلاعات execution context در اون ذخیره شده. منظور از اطلاعات، variables و function declarations و arguments هایی است که داخل execution context ذخیره شدن.اگه از بخش اول یادتون باشه، برای اینکه مفهوم execution context رو بهتر درک کنیم، اون رو به یه جعبه تشبیه کردیم. حالا برای اینکه مفهوم variable object رو هم بهتر درک، اون رو هم به عنوان یه جعبه‌ی کوچک در نظر بگیرین که داخل execution context قرار گرفته و در واقع اطلاعات ذخیره شده در  execution context در این جعبه و این قسمت از  execution context ذخیره می‌شن.خب الان بیاین کد زیر رو که در global execution context نوشته شده، بررسی کنیم:var a = 100;
var b = &amp;quothello world&amp;quot
function foo () {}با توجه به گفته‌های بالا variable object ساخته شده برای global execution context شامل اطلاعات زیر می‌شه:1- var a2- var b3-  foo ()2- scope chain:scope:دسترسی به variable ها به وسیله scope تعین می‌شه. یعنی variable هایی که داخل یه scope تعریف شدن، خارج از اون قابل دسترس نیستن. scope باعث می‌شه variable ها فقط در داخل قسمت‌های مشخص شده‌ای از برنامه که به وسیله ما تعین شده قابل استفاده باشن. در جاوااسکریپت 3 نوع scope داریم:1- global scope:همون طور که global execution context داریم، یه global scope هم داریم که به محض ایجاد global execution context، به صورت پیش‌فرض توسط موتور جاوااسکریپت ایجاد می‌شه و تمام scope هایی که بعدا ایجاد می‌شن scope درونی یا فرزند global scope هستن. هر variable که در global scope تعریف شده در همه جای برنامه قابل دسترس است.var message= &#039;Hello World!&#039;;
function sayHello() {
  console.log(message); // return Hello World!
}
sayHello();2- Local Scope or Function Scope:با نوشتن، فراخوانی و ساخت فانکشن می‌شه یه scope جدید ساخت که به این نوع از scope ها Function Scope یا Local Scope گفته ‌می‌شه.function sayHello() {   
var message= &#039;Hello World!&#039;; 
console.log(message); // return Hello World! 
} 
sayHello();
console.log(message); // return message is not definedاگه کد بالا رو تو کنسول مرورگر اجرا کنیم، تو خط 3 کد، «Hello World!» برای ما برگشت داده می‌شه چون  var message داخل فانکشن ()sayHello تعریف شده و فانکشن ()console.log خط 3 هم چون داخل این فانکشن و در نتیجه داخل این scope است پس بهش دسترسی پیدا می‌کنه و «Hello World!» برگشت داده می‌شه. ولی چون فانکشن ()console.log خط 6 خارج از scope و فانکشن ()sayHello نوشته شده بنابراین به var message دسترسی نداره.3- block scope:به محدوده‌ی بین دو براکت بلاک اسکوپ گفته می‌شه. (در let ،ES6 و const داخل { } قابل دسترس هستند و در واقع بین دو { }، یک اسکوپ ایجاد می‌شه.){
var first = &#039;first message.&#039;;
let second = &#039;second message&#039;;
const third = &#039;third message&#039;;
}
console.log(first); // return &#039;first message&#039;.
console.log(second); // return second is not defined
console.log(third); // return third is not definedبا توجه به کد بالا به این نتیجه می‌رسیم که متغیر var بر خلاف let و const از نوع block scope  نیست و خارج از { } هم قابل دسترسه.تا اینجا با مفهوم scope آشنا شدیم ولی این همه‌ی مواردی که باید درباره‌ scope بدونیم نیست. الان وقتشه درباره‌ lexical scoping بحث کنیم.lexical scope: در جاوااسکریپت lexical scoping به این معنی و مفهوم است که scope های درونی به scope های بیرونی دسترسی دارند. یعنی اگه یه variable در یه scope تعریف شده، scope (های) درونی اون می‌تونن به اون variable دسترسی پیدا کنن. ولی scope (های) بیرونی نمی‌تونن به اون variable دسترسی پیدا کنن.** یک نکته مهم که باید بهش توجه داشته باشیم اینه که scope ها مستقیما به variable (ها) دسترسی ندارن. در واقع scope ها به variable object ها دسترسی پیدا می‌کنن و چون variable ها داخل variable object ها ذخیره شدن، از این طریق دسترسی حاصل می‌شه.بیایین کد زیر رو  تو 3 مرحله بررسی کنیم:var a = &#039;north London &#039;;
first();
function first () {
var b = &#039;is &#039;;
second();
function second () {
var c = &#039;red.&#039;;
console.log(a + b + c); // return &amp;quotnorth London is red.&amp;quot
}
}  1- مرحله اول:یه global scope داریم و همون طور که قبلا گفته شد به محض ایجاد global execution context، به صورت پیش‌فرض توسط موتور جاوااسکریپت ایجاد می‌شه و تمام scope هایی که بعدا ایجاد می‌شن scope درونی یا فرزند global scope هستن. یه scope توسط ()first ایجاد شده که scope درونی یا فرزند global scope است و یه scope هم توسط فانکشن () second ایجاد شده که scope درونی یا فرزند first() scope و global scope است.2- مرحله دوم:در var a ،global scope تعریف شده. var b داخل فانکشن ()first و var c داخل فانکشن () second تعریف شدن.3- مرحله سوم:  درونی‌ترین scope در کد بالا second() scope است. پس این scope به variable object دو scope بیرونی دسترسی پیدا می‌کنه و چون var a و var b داخل variable object ها ذخیره شدن، این دسترسی حاصل می‌شه و مقدار «.north London is red» برگشت داده می‌شه. در حالی که اگه ()console.log داخل فانکشن ()first بود مقدار «c is not defined» برگشت داده می‌شد. و اگه داخل global scope بود ابتدا «b is not defined» و بعدا «c is not defined» برگشت داده می‌شد.VO= global objectscope chain:تو کد بالا دیدیم که فانکشن ()console.log حاصل جمع سه var رو بدون هیچ اروری برگشت داد و این یعنی فانکشن ()console.log به هر سه var دسترسی پیدا کرده. در واقع var c تو همون second() scope قرار داره و طبیعیه که بهش دسترسی داشته باشه، چون باهم تو یه scope قرار گرفتن. ولی او دو تا var دیگه تو اون scope نیستن، بنابراین موتور جاوااسکریپت با استفاده از ویژگی lexical scoping جاوااسکریپت به scope های بیرونی مراجعه می‌کنه تا شاید مقدار اون دو تا var رو پیدا کنه که در مرحله اول می‌رسه به first() scope. تو این scope هم var b تعریف شده و مقدار این متغیر پیدا می‌شه. ولی هنوز مقدار var a مشخص نشده، بنابراین در مرحله دوم موتور جاوااسکریپت یه مرحله جلوتر می‌ره و مراجعه می‌کنه به scope بیرونی‌تر و آخرین scope موجود که همون global scope هست. تو این scope هم var a مشخص شده و تمام variables مقدارشون مشخص می‌شن و کدی که نوشتیم بدون هیچ اروری نتیجه رو به ما برگشت می‌ده.پس اگه یه variable تو scope فعلی مقدارش مشخص نشده باشه، موتور جاوااسکریپت تو scope های بیرونی‌تر دنبالش می‌گرده و این جستجو تا آخرین scope بیرونی که همون global scope است ادامه پیدا می‌کنه و اگه اونجا هم پیدا نشه برنامه ارور می‌ده. همه‌ی این اتفاق‌ها به لطف scope chain هست. scope chain جاییه که نه‌تنها variable object اون scope ذخیره شده بلکه یه راه ارتباطی هم وجود داره تا scope های درونی به variable object های scope های بیرونی دسترسی پیدا کنن. و این در حالیه که این ارتباط یه طرفست و فقط scope درونی می‌تونه به scope های بیرونی دسترسی داشته باشه.* درواقع می‌شه scope chain یه execution context رو دربردانده variable object اون scope و execution context دونست که به variable objectهای scope ها و execution context های بیرونی دسترسی داره.تا اینجا با 2 تا از پراپرتی‌های execution context آشنا شدیم ولی پراپرتی سوم رو تو بخش سوم مقاله باهم بررسی میکنیم.</description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Fri, 08 Nov 2019 11:15:40 +0330</pubDate>
            </item>
                    <item>
                <title>پشت‌ پرده جاوااسکریپت- بخش 1</title>
                <link>https://virgool.io/@ehsan_n/%D9%BE%D8%B4%D8%AA-%D9%BE%D8%B1%D8%AF%D9%87-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A8%D8%AE%D8%B4-1-ajxyrhfaqf6f</link>
                <description>در این مقاله که به خاطر زیاد بودن مطالب مجبور شدم تو چند پست جدا بنویسم، می‌خایم کمی متفاوت‌تر از آموزش‌های موجود، زبان جاوااسکریپت رو باهم بررسی کنیم. این مطالب و مفاهیم در برخورد اول برای دولوپرهای تازه‌کاری مثل من، شاید گیج‌کننده باشن و نتایجی هم که خواهیم‌گرفت ساده به نظر برسن  و احتمالا قبلا هم می‌دونستین ولی هدف از این پست اینه که مسائل رو کنار نتایج قرار بدیم تا دیدمون نسبت به جاوااسکریپت وسیع‌تر بشه و بهتر از این زبان استفاده کنیم. Execution Context:در جاوااسکریپت execution context یک مفهوم انتزاعی و فرضی است که اطلاعات (this keyword, objects variables, functions) قسمتی از کد که در حال تفسیر و اجرا توسط موتور جاوااسکریپت (javascript engine) است در آن ذخیره شده. به عبارت بهتر هر زمانی که کد در جاوااسکریپت اجرا می‌شه در واقع داخل یک execution context این اتفاق می‌افته.برای درک بهتر می‌تونیم execution context رو یک جعبه در نظر بگیریم که یه سری کد داخلش نگهداری می‌شه و وقتی نوبت اجرا و تفسیرش می‌رسه اون اطلاعات رو در اختیار مفسر یا همون موتور جاوااسکریپت (javascript engine) قرار می‌ده.می‌شه execution context رو به عنوان یک شئ (object) هم در نظر گرفت که ویژگی‌هایی (properties) هم داره. فعلا این رو تو ذهنتون نگه‌دارین، بعدا راجع به این موضوع بیشتر صحبت می‌کنیم.در جاوااسکریپت 3 نوع execution context داریم:Global Execution ContextFunctional Execution ContextEval Function Execution ContextGlobal Execution Context:در مرورگر execution context پیش‌فرض، global execution context هست. کدی که داخل هیچ فانکشنی نوشته نشده، در global execution context ذخیره می‌شه. اگر execution context رو به عنوان object درنظر بگیریم، global execution context هم به عنوان global object شناخته می‌شه.* در مرورگر، window object همون global object هست. * در هر صفحه وب فقط یک global object وجود داره.اگه کد زیر رو تو کنسول مرورگر بنویسین، window object رو به عنوان نتیجه می‌بینین:console.log(this);     //return window objectFunctional Execution Context:هر فانکشن یه execution context مختص به خودش رو داره ولی تا زمانی که فانکشن فراخوانی نشده، execution context اون فانکشن ساخته نمی‌شه. تو این مقاله ما بیشتر راجع به این نوع execution context صحبت می‌کنیم.پس هر وقت یک فانکشن فراخوانی شد یه execution context مختص به اون فانکشن هم ساخته می‌شه.با کمی دقت به تصویر بالا به این نتیجه می‌رسیم که در هر برنامه به تعداد فراخوانی‌های فانکشن‌ها، functional execution context داریم. یعنی اگر تعداد فراخوانی‌ها 10 تا باشه به همون تعداد هم  functional execution context داریم.** چون فانکشن ()eval خیلی کم کاربرد داره و همچنین فانکشن دردسرسازی هم هست، درباه‌ی Eval Function Execution Context بحث نمی‌کنیم. اگه می‌خاین دربارش بیشتر بدونین، اینجا رو مطالعه کنین.خب تا این جای کار با execution context و انواع اون آشنا شدیم و کاربرد هر کدوم رو فهمیدیم. حالا بریم درباره‌ی یک مفهوم دیگه به نام execution stack صحبت کنیم.Execution Stack:یک ساختار داده‌ای هست که execution context هایی که به وسیله‌ی فراخوانی فانکشن‌ها ساخته شدن، در این ساختار و بستر ذخیره می‌شن. execution stack از مکانیزم LIFO) Last In, First Out) استفاده می‌کنه. برای درک بهتر، execution stack رو به عنوان یک دودکش! در نظر بگیریم که execution context ها به ترتیب از بالای دودکش میان و می‌رن اون پایین قرار می‌گیرن و ذخیره می‌شن و هنگام برگشت داده شدن (return)، آخرین و بالاترین execution context، اولین execution context خواهد بود که برگشت داده می‌شه که همون مکانیزم LIFO هست.  * باید به این نکته توجه داشت که همیشه global execution context، اولین execution context ذخیره شده در execution stack هست.خب حالا بیاین کد زیر رو با توجه به گفته‌های بالا بررسی کنیم:var a = &#039;message&#039;;
function first () {
var b = &#039;first function&#039;;
second();
var x = b + a;
}
function second () {
var c = &#039;second function&#039;;
third();
var y = c + a;
}
function third () {
var d = &#039;third function&#039;;
var z = d + a;
}
first();1- مرحله اول:در اولین مرحله کدهایی که داخل هیچ فانکشنی نیستن، تو global execution context ذخیره می‌شن. یعنی از خط 1 کدمون تا قبل از فراخوانی فانکشن ()first. باید به این نکته توجه داشته باشیم همون طور که قبلا هم بررسی کردیم، نوشتن یک فانکشن باعث نمی‌شه execution context مختص اون فانکشن ساخته بشه، بلکه باید اون فانکشن فراخوانی بشه تا execution context مختص بهش هم ساخته بشه.2- مرحله دوم:در این مرحله به محض اینکه فانکشن ()first فراخوانی شد، execution context مختص بهش هم ساخته می‌شه و کدهای این فانکشن داخل execution context ذخیره و اجرا می‌شن. الان execution context فعال، first execution context هست که در execution stack، بالای global execution context قرار می‌گیره.ابتدا var b داخل execution context ذخیره می‌شه و بعد نوبت به خط بعدی کد می‌رسه. تو این خط از کد، فانکشن ()second فراخوانی می‌شه. 3- مرحله سوم:خب فکر کنم دیگه همه می‌دونیم چه اتفاقی می‌افته؟بله درسته، به محض اینکه فانکشن ()second فراخوانی می‌شه، مثل مرحله قبل یه execution context مختص به فانکشن ()second هم ساخته می‌شه و execution context فعال، second execution context می‌شه که در execution stack، بالای first execution context قرار می‌گیره.در این مرحله هم var c داخل execution context ذخیره می‌شه و بعد نوبت به خط بعدی کد می‌رسه. تو این خط از کد، فانکشن ()third فراخوانی می‌شه.4- مرحله چهارم:در این مرحله هم مثل مراحل دوم و سوم بعد از فراخوانی فانکشن، execution context مختص به فانکشن ()third هم ساخته می‌شه که در این مرحله execution context فعال هم هست و بالاتر از بقیه execution context ها قرار می‌گیره و همچنین var d داخل اون ذخیره می‌شه.5- مرحله پنجم:بعد اینکه third execution context ساخته و کدهای داخل اون تفسیر شدن نوبت به برگشت داده شدن (return) این execution context و حذفش از execution stack هست. این عمل برای دو function execution context دیگه و global execution stack هم تکرار می‌شه تا از execution stack حذف بشن. این همون مکانیزم LIFO  هست که آخرین execution context که در execution stack قرار گرفته، اول از همه هم برگشت داده می‌شه و اولین execution context آخر از همه برگشت داده می‌شه . پس به ترتیبی که در مراحل بالا دیدیم، موتور جاوااسکریپت کد ما رو اجرا و تفسیر کرد. http://vrgl.ir/JHH18 </description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Fri, 25 Oct 2019 11:14:28 +0330</pubDate>
            </item>
                    <item>
                <title>Parse CSS-2</title>
                <link>https://virgool.io/JavaScript8/parse-css-2-onjjgleulrp3</link>
                <description> در بخش اول این مقاله درباره  resolve conflicting CSS declaration  یه سری نکات گفته شد و در این پست درباره مرحله دوم Parse CSS یعنی proccess final CSS value  بحث می کنیم.  بهتره برای قابل درک و شفاف تر بودن نکات، همراه با مثال پیش بریم: همون طور که میبینین در قسمت CSS سه  Declaration Block  نوشته شده که تو هر کدوم چن تا  Declaration  هست و  Property  هر کدوم از Declaration  ها دارای مقدار (Value) خاصی هست.این Value ها برای اینکه مرورگر بتونه به المنت ها اعمال کنه 6 مرحله رو طی میکنن:1-  از بین تمام کدهای CSS که دولوپر نوشته ( Author ) تمام مقادیری که به Property های CSS تگ اعمال شدن شناسایی میشن. در مثال بالا برای پراپرتی width تگ p دو مقدار مختلف اعمال شده که هر دو شناسایی و آماده ی اعمال میشن. (Declared Value)2-  چون تو خیلی از موارد ممکن هست به یکی از Property های CSS در چند Declaration  مختلف چندین مقدار تعین بشه  در مرحله ی دوم  با توجه به اولویت بندی  Selector ها که در بخش اول مقاله دربارشون بحث شد، فقط یکی از اون مقادیر انتخاب میشه. پس width تگ p که بهش دو مقدار مختلف اعمال شده با توجه به اینکه اولویت سلکتور text.  بالاتر از سلکتور ، p هست، برابر با 63% میشه. در این مرحله از Declaration هایی که در سورس های دیگه هم نوشته شده استفاده میشه. (Cascaded Value)3- با توجه به قانون CSS، همه Property های CSS یک المنت باید مقدار (value) داشته باشن. در این مرحله حتی اگه دولوپر برای اون Property مقداری تعین نکرده باشه، مقدار پیش فرض اون Property اعمال میشه. در مثال بالا برای Property های padding یا margin تگ p هیچ مقداری تعین نشده ولی مقدار پیش فرض اون پراپرتی ها که برابر با 0px اعمال میشه. (Specified Value)4-   در مرحله چهار مقادیری که واحد Relative دارن (rem, em, vh, vw)  به مقداری با واحد Absolute که همون px هست تبدیل میشن. CSS Keyword  هایی مثل pink برای Property های color و background-color و یا bold و bolder برای font-weight هم به مقدار Absolute تبدیل میشن. (Computed Value)5-   در این مرحله محاسبه ی نهایی انجام میشه و تمام مقادیر با واحد Absolute آماده ی اعمال میشن. در مثال بالا برای تگ p مقدار width برابر 63 درصد width تگ پدرش(Parent Tag) هست که مقدار اون برابر با 226.8 px میشه. (Used Value)(360px) * (63%) = 226.8 px6-  در مرحله آخر مقادیری که اعشار دارن گرد میشن تا به صورت عدد صحیح در بیان تا مرورگر بتونه تفسیرشون کنه. (Actual Value)پس :226.8 px = 227 pxبا توجه به مراحل بالا، Property های زیر به این شکل محاسبه میشن:1- مقدار width ،Property تگ p :در دو Declaration مختلف، دو مقدار متفاوت برای width ،Property این تگ اعمال شده:p{
    width: 140px;
}.text{
    width: 63%;
}با توجه به اولویت بندی Selector ها فقط مقدار 63% برای width ،Property اعمال میشه .در این مرحله چون مقداری تعین شده پس از مقدار پیش فرض استفاده نمیشه.چون واحدمون rem , em , vh , vw نیست تبدیلی در این مرحله اتفاق نمیفته.در نهایت مقدار نهایی 63% از طول تگ پدر تگ p محاسبه میشه و با واحد px اعمال میشه که قبلا محاسبه کردیم.عدد بدست آمده گرد و مقدار نهایی 227px اعمال میشه. 2- مقدار padding ،Property تگ p :چون هیچ مقداری padding ،Property تگ p نوشته نشده پس در مراحل 1 و 2 هیچ کاری صورت نمیگیره.در مرحله 3 چون هیچ مقداری padding ،Property تگ p نوشته نشده، مقدار پیش فرض اون جایگذاری میشه که برابر با 0px هست.در مراحل  4 و 5 چون واحد اعمال شده px هست پس هیچ کاری صورت نمیگیره.در مرحله 6 هم چون مقدار برابر یک عدد صحیح است باز هیچ کاری صورت نمیگیره و مقدار 0px برای padding ،Property تگ p اعمال میشه.3- مقدار font-size ،Property روت (body و html) :چون  بین کد های CSS برای تگ های &lt;body&gt; و &lt;html&gt; هیچ font-size تعین نشده پس در این مرحله کاری صورت نمیگیره.در مرحله دوم font-size پیش فرضی که همه مرورگرها در فایل CSS پیش فرض خودشون(User Agent) دارن اعمال میشه که معمولا برابر با 16px هست.مراحل بعدی چون واحد مقدار Property  از نوع Absolute هست (px) و هم عدد صحیح پس بدون هیچ پردازشی طی میشن و 16px ،font-size به روت اعمال میشه.4- مقدار font-size ،Property تگ &lt;&quot;div class=&quot;wrapper&gt; :در مرحله  اول مقدار 2rem که در کدهای CSS نوشته شده شناسایی و اعمال میشه.چون فقط یک مقدار اعمال شده پس همون هم انتخاب میشه.در مرحله سوم هم چون مقدار تعین شده، پس هیچ کاری صورت نمیگیره.در این مرحله واحد rem به px تبدیل میشه. 1rem برابر با فونت سایز root هست. پس: 1rem = 16px    =====&gt; (2rem) * (16px) = 32px در مراحل بعدی هم هیچ کاری صورت نمیگیره و همون 36px اعمال میشه.5- مقدار font-size ،Property تگ &lt;p&gt; :چون بین کدهای CSS که توسط دولوپر نوشته شده (Author)  هیچ مقداری برای font-size ،Property تگ p نوشته نشده پس در مراحل اول و دوم هیچ کاری صورت نمگیره.در مرحله سوم چون هیچ مقداری تعین نشده پس مرورگر از مقدار پیش فرض استفاده میکنه. برای font-size مقدار پیش فرض برابر با مقدار font-size تگ پدر اون تگ هست. یعنی فونت سایز تگ p برابر با font-size تگ &lt;&quot;div class=&quot;wrapper&gt; هست . بنابراین مقدارش برابر با 32px میشه.اینجا هم چون واحد مقدار px هست و عددش هم صحیح در مراحل بعدی هیچ کاری صورت نمیگیره.</description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Fri, 03 Aug 2018 23:54:02 +0430</pubDate>
            </item>
                    <item>
                <title>Parse CSS-1</title>
                <link>https://virgool.io/JavaScript8/parse-css-cwcwgdxyt6uf</link>
                <description>وقتی یک صفحه ی وب رو باز میکنیم، همه ی مراحل عکس بالا طی می شن تا صفحه لود شده و به ما نمایش داده بشه. اگه به شکل دقت کنین ابتدا سند HTML لود و بعد پارس شده و  همزمان با پارس شدن سند HTML، سند (های)  CSS  هم لود و پارس میشن. در این پست در باره ی این مرحله بحث می کنیم. پارس شدن سند(های) CSS شامل دو مرحله هست:1-resolve conflicting CSS declaration 2-proccess final CSS valueدر این پست درباره ی مرحله ی 1 یه سری نکات رو توضیح میدم.قبل از این که مرحله یک رو شرح بدم باید دو تا نکته رو یادآوری کنم:1- قانون نوشتاری CSS :سلکتور میتونه نام تگ، کلاس، آیدی و یا تلفیقی از این سه مورد باشه.به کدهای داخل اسکوپ Declaration Block گفته میشه. هر Declaration Block میتونه شامل یک یا چند Declaration باشه.هر Declaration از دو قسمت Property  و  Value تشکیل شده.2- سه نوع سورس CSS داریم:کدهای CSS که دولوپر(های) پروژه نوشتن.(Author)کدهای CSS که به وسیله ی کاربر ایجاد می شن. به عنوان مثال وقتی کاربر اندازه فونت صفحه رو از طریق تنظیمات مرورگر عوض میکنه.(User) کدهای CSS که به صورت پیش‌فرض در هر مرورگر وجود داره.(User Agent) خب، با یک مثال بریم سراغ بحث اصلی: برای Property رنگ تگ h1  چندین Declaration به صورت زیر نوشته شده ولی در نهایت h1  قرمز شده.ولی سوال اینجاست که مرورگر با چه قانونی این Declaration ها رو اولویت‌بندی میکنه تا در نهایت رنگ تگ قرمز بشه؟قوانین اولویت CSS :1- در مرحله اول، Declaration ها به ترتیب زیر وزن‌دهی میشن:1- User !important2- Author !important3- Author Declarations4- User Declarations5- Default Browser Declarationsپس Declarationهایی که important دارن بیش‌ترین وزن رو هم دارن.بعد از این دو مورد Declarationهایی که به وسیله دولوپر(ها)، CSS های ایجاد شده به وسیله ی کاربر و کد های CSS موجود در سورس پیش‌فرض مرورگر هم به ترتیب دارای بیش‌ترین وزن هستن.اما اگه وزن دو Declaration باهم برابر باشه، یعنی به طور مثال هر دو Declaration در سورسی که دولوپرها نوشتن باشه مرورگر وارد مرحله دوم میشه.2- در مرحله دوم Declaration ها به ترتیب زیر اولویت‌بندی میشن:1-Inline Style2- IDs3- Classes, Pseudo-classes4- Elements, Pseudo-elementsاعمال استایل به تگ باتوجه به اولویت‌بندی بالا و فرمول زیر هست:(Inline Style, IDs, Classes Pseudo-classes attributes, Elements, Pseudo-elements)به عنوان مثال به Selector زیر دقت کنین:div p.title:hover #id .post .item:afterInline Style : 0ID : 1Classes, Pseudo-classes, attributes : 4Elements, Pseudo-elements : 3پس امتیاز این Selector به صورت زیر هست:(0 ,1 ,4 ,3)و هر Selector که امتیازش بیش‌تر باشه از اولویت بیش‌تری هم برخوردار هست.الان می تونیم امتیاز Selector هایی که در مثال بالا آوردم رو محاسبه کنیم و بفهمیم اولویت با کدوم هست:h1{}Inline Style : 0ID : 0Classes, Pseudo-classes, attributes  : 0Elements, Pseudo-elements : 1(0, 0, 0, 1).container .h1{}Inline Style : 0ID : 0Classes, Pseudo-classes, attributes  : 1Elements, Pseudo-elements : 1(0, 0, 1, 1).container #header .h1{}Inline Style : 0ID : 1Classes, Pseudo-classes, attributes  : 1Elements, Pseudo-elements : 1(0, 1, 1, 1)پس به همن دلیل رنگ تگ h1 قرمز شده.3- در مرحله سوم و پایانی اگر اولویت Declaration  ها هم برابر باشند، اولویت با  آخرین Declaration هست. با توجه به گفته های بالا باید به چند نکته توجه بشه:هر Declaration که دارای important باشه، بالاترین اولویت رو داره.(استفاده از important راحت‌ترین راه برای رفع اشکلات هست ولی اگه زیاد استفاده بشه ممکنه بعدا مشکلات بزرگ‌تری به وجود بیاره.)استایل‌های inline اولویت بالاتری نسبت به استایل های external دارن. (استایل‌هایی که با استفاده از DOM اعمال میشن هم inline به حساب میان.)سلکتوری که فقط 1 آیدی داره اولویتش از سلکتوری که 100 کلاس داره بیشتره! و همین طور سلکتوری که 1 کلاس داره اولویتش از سلکتوری که 100 المنت داره بیش تره!سلکتور * (Universal Selector) هیچ امتیازی با توجه به فرمول بالا نداره! (0 ,0 , 0, 0)</description>
                <category>Ehsan</category>
                <author>Ehsan</author>
                <pubDate>Fri, 27 Jul 2018 14:17:44 +0430</pubDate>
            </item>
            </channel>
</rss>