<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های ابوالفضل رضوانی نراقی</title>
        <link>https://virgool.io/feed/@rezvani2647</link>
        <description>فقط میخوام در آموزش سهمی داشته باشم و اگر بتونم مفید باشم خوشحال میشم.</description>
        <language>fa</language>
        <pubDate>2026-06-17 00:39:59</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/69549/avatar/B3NXId.jpeg?height=120&amp;width=120</url>
            <title>ابوالفضل رضوانی نراقی</title>
            <link>https://virgool.io/@rezvani2647</link>
        </image>

                    <item>
                <title>Hoisting – scopes – closures در زبان javascript</title>
                <link>https://virgool.io/@rezvani2647/hoisting-scopes-closures-%D8%AF%D8%B1-%D8%B2%D8%A8%D8%A7%D9%86-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-jwcixcn1empu</link>
                <description>سلام در مورد تایتل خواستم مطلب بنویسم و یه مقاله پیدا کردم که به نظرم فوق العاده کامل بود و خوب توضیح داده بود بنابر این تصمیم گرفتم اونو براتون ترجمه کنم. لینکشم میگذارم تا اگر از ترجمه خوشتون نیومد اصل مطلب و بخونید.مقاله زبان اصلیjavascript-visualizerشاید به نظر عجیب بیاد ولی به نظر من مهم ترین قسمت از اصول اولیه در فهمیدن زبان جوااسکریپت فهمیدن Execution Context باشد. با درک درست از آن میتوانید برای فهمیدن قسمت های پیش رفته جاوااسکریپت در جایگاه درستی قرار بگیرید. با این درک باید به این سوال پاسخ دهیم که اصلا Execution Context چی هست ؟ برای درک درست از آن ابتدا باید ببینیم چگونه یک نرم افزار نوشته می شود.یک روش در نوشتن یک نرم افزار این است که کد را به قسمت های ریزتری بشکنیم. حالا این قسمت ها ممکنه اسامی مختلفی داشته باشن (توابع، ماژول، پکیج و ... ).همه آنها برای یک هدف قرار گرفته اند برای شکستن و مدیریت قسمت های پیچیده در نرمافزار.حالا به جای اینکه مثل کسی که کد میزنه فکر کنیم بیایم مثل موتور جاوااسکریپت که کد رو ترجمه می کنه و به زبان ماشین برگردونه فکر کنیم. آیا میتونیم از همون روش استفاده کنیم و کد رو برای مدیریت پیچیدگی هاش به قسمت های کوچکتری بشکنیم ؟مشخص میشه که میتونم و به این تکه ها Execution Contextمیگیم.همان طور که توابع ، ماژول ها و پکیج ها به شما اجازه می دهند تا پیچیدگی های کد خودتون رو مدیریت کنید Execution Contexts به موتور جاوااسکریپت اجازه میده تا پیچیدگی ترجمه و اجرای کد شما رو مدیریت کنه. حالا که فهمیدیم Execution Contexts چیه باید به این سوال جواب بدیم که کی ایجاد میشن و شامل چه چیزی هستن ؟اولین Execution Contexts که ایجاد می شود تا کد شما رو اجرا کند به آن “Global Execution Context” گفته می شود که شامل دو چیز است یک global object و متغییری که به آن this  گفته میشود. this به global object رجوع می کند که در محیط مرورگر همان window  و در محیط node  همان global  است.در تصویر بالا میتوانیم ببینم که بدون هیج کدی Global Execution Context شامل دو چیز میشود window و this. این Global Execution Context در ساده ترین حالتشه.حالا ببینیم چه اتفاقی می افتد وقتی دست به کد می شویم. بگذارید چندتا متغییر اضافه کنیم.میتونید فرق بین دو تصویر بالا رو تشخیص بدید ؟ فرقش اینه که هر Execution Context دارای دو فاز هست، فاز  Creation   و فاز Execution   که میشه فاز ایجاد و فاز اجرا که هر کدام وظایف خاص خودشونو دارن.در فاز Global Creation موتور جاوااسکریپت به سکل زیر عمل خواهد کرد.1- ایجاد Object  Global2- ایجاد Object  this3- قرار دادن فضای مورد نیاز برای متغیر ها و توابع در حافظه4- اعمال مقدار پیش فرض undefined برای متغییر های تعریف شده در حالی که هر تابع را درون حافظه قرار میدهد.تا زمانی که وارد فاز Execution  نشویم موتور جاوااسکریپت کد شما رو خط به خط اجرا نمی کند در گیف زیر میتوانیم این فازها را مشاهده کنیم.در طول ایجاد فاز Creation  ، window و this  ایجاد می شوند. متغییرهایی که تعریف شده اند مقدار undefined  میگیرند و هر تابعی که تعریف شده است getUser به طور کامل در حافظه قرار می گیرد. و هنگامی که ما وارد فاز Execution  میشویم موتور جاوااسکریپت خط به خط کد ما را بررسی می کند و مقادیری که برای متغییر هایی که اکنون در حافظه هستند تعریف کرده بودیم در آنها قرار می گیرد.برای اینکه بحث Creation Execution را درک کنید بیایید قبل از مرحله Execution  و بعد از مرحله Creation  چیزیهایی چاپ کنیم.console.log(&#039;name: &#039;, name)
console.log(&#039;handle: &#039;, handle)
console.log(&#039;getUser :&#039;, getUser)
var name = &#039;Tyler&#039;
var handle = &#039;@tylermcginnis&#039;
function getUser () {
         return {name: name,handle: handle}
}در مرحله فوق چه چیزی توقع دارید تا در console  چاپ شود ؟ در زمانی که javascript  شروع به اجرای کد ما به شکل خط به خط میکند و console.log() های مارا فراخوانی می کند فاز Creation  قبلا اتفاق افتاده است. همان طور که قبلا دیدیم متغییر هایی که تعریف شده بودند باید مقدار undefined  میداشتند و توابعی هم که تعریف شده بودند باید کاملا در حافظه قرار می داشتند. پس همانطور که توقع داریم مقدار name و handle برابر با undefined و getUser هم به تابع در حافظه ارجاع داده شده است.console.log(&#039;name: &#039;, name) // name: undefined
console.log(&#039;handle: &#039;, handle) // handle: undefined
console.log(&#039;getUser :&#039;, getUser) // getUser: ƒ getUser () {}

var name = &#039;Tyler&#039;
var handle = &#039;@tylermcginnis&#039;

function getUser () {
   return {
        name: name,
        handle: handle,
     }
}به این مرحله از پردازش که مقدار متغییر های تعریف شده برابر با undefined قرار میگیرید hoisting گفته میشود. چیزی که باعث میشه  “hoisting” فهمش گیج کننده باشه اینه که چیزی در حقیقت hoisted نمیشه یا  در اطراف حرکت نمی کند. اما حالا که Execution Contexts را می دانید و میدانید که متغییر هایی که تعریف می شوند مقدار undefined  در فاز Creation  دارند. شما hoisting را متوجه می شوید چون به معنای واقعی همینه که گفتم.از این نقطه به بعد شما باید با Global Execution Context و فازهای Creation  و Execution راحت باشید. خبر خوب اینه که فقط یک Execution Context دیگر باقی مانده است تا یاد بگیرید و اونم عینه Global Execution Context میمونه و بهش Function Execution Context  میگن و وقتی ایجاد میشه که تابعی فراخوانی میشه.تنها زمانی که  Execution Context ایجاد و هر زمانی که تابعی فراخوانی شود میشه زمانی هست که موتور جاوااسکریپت شروع به ترجمه کد شما می کند. حالا سوال اصلی که باید جواب بدیم اینه که چه فرقی بینGlobal Execution Context  و یک Function Execution Context است ؟ اگر از قبل به خاطر داشته باشید گفته بودیم که در فاز Global Creation:1- ایجاد Object  Global2- ایجاد Object  this3- قرار دادن فضای مورد نیاز برای متغیر ها و توابع در حافظه4- اعمال مقدار پیش فرض undefined برای متغییر های تعریف شده در حالی که هر تابع را درون حافظه قرار میدهد.کدام مورد هنگامی که در مورد Function Execution Context صحبت می کنیم معنی نمی دهد ؟ دقیقا قدم اول شماره 1.ما باید فقط یک global object  داشته باشیم که آن هم فقط در زمانه فاز Creation  در Global Execution Context است نه هر زمانی که تابعی فراخوانی می شود و موتور جاوااسکریپت یک  Function Execution Context ایجاد می کند. به جای اینکه یک global object  ایجاد کنیم تنها چیزی که یک  Function Execution Context نیاز دارد که نگران آن باشد این است که Global Execution Context آرگومان ندارد. با توجه به این میتوانیم لیست قبلی را به این لیست تغییر دهیم: هنگامی که Function Execution Context ایجاد می شود موتور جاوااسکریپت ..1- یک global object  ایجاد می کند.1- آبجکت آرگومان ها را ایجاد می کند.2- آبجکتی به نام this  ایجاد میکند.3- برای متغییر ها و توابع تعریف شده حافظه اختصاص می دهد.4- هنگامی که توابع تعریف شده را در حافضه قرار می دهد برای متغییر های تعریف شده مقدار پیشفرضundefined  را قرار می دهد.برای دیدن این در عمل به کدی که در قبل داشتیم باز می گردیم ولی این بار به جای اینکه فقط getUser را تعریف کنیم ببنیم چه می شود اگر آن را فراخوانی کنیم.همانطور که در قبل صحبت کردیم هنگامی که getUser  را فراخوانی می کنیم یک  Execution Context ایجاد می شود.  در طول فاز ایجاد  Execution Context برای getUsers  ، موتور جاوااسکریپت آبجکتهای this و arguments  را ایجاد می کند. به خاطر اینکه getUser  متغییری ندارد موتور جاوااسکریپت نیازی ندارد تا فضای حافظه ای تنظیم کند یا متغییر تعریف شده ای  “hoist” کند.شاید متوجه شده باشید که وقتی که اجرای getUser  به پایان می رسد از دیده هم خارج می شود. در واقعیت موتور جاوااسکریپت چیزی ایجاد می کند به نام “Execution Stack” (که به “Call Stack” هم معروف است). هر زمان که تابعی فراخوانی می شود یک  Execution Context ایجاد می شود و به Execution Stack اضافه می شود. هنگامی که پردازش تابعی در فاز Creation و Execution  به اتمام می رسد. از Execution Stack خارج می شود. و از آنجایی که javascript  تک نخی است )به این معنی است که فقط یک کار در لحظه میتواند اجرا شود)، که به راحتی قابل مشاهده است.در اینجا می بینیم که چگونه در فراخوانی ها توابع Execution Context خودشان را درون  Execution Stack قرار می دهند. چیزی که هنوز ندیدم این است که متغییر های محلی چه نقشی در آن دارند. بیاید کد را تغییر دهیم تا تابع ما متغییر محلی داشته باشد.در اینجا نکات ریز و مهمی هست که باید بدانید. هر متغییری که در تابع به عنوان آرگومان پاس بدهید درون تابع به عنوان متغییر محلی خواهد بود. در مثال بالا متغییر handle در Global Execution Context (به خاطر اینکه تعریف شده است) و getURL Execution Context (به خاطر اینکه به عنوان آرگومان) وجود دارد. و نکته بعدی اینکه متغییری که در داخل تابعی تعریف میشود درون Execution Context آن تابع زندگی می کند. پس هنگامی که twitterURL ایجاد میکنیم درون getURL Execution Context زندگی میکند نه در Global Execution Context چرا که آنجا جایی است که تعریف شده است. شاید به نظر واضح باشه ولی از نکات حیاتی مطلب بعدی است.در گذشته شاید تعریف scope  را  ‘جایی که به متغییر ها دسترسی داریم’ شنیده باشید. ولی در اصل MDN آن را &quot;context   کنونی در حال اجرا &quot; تعریف می کند. ما میتوانیم به “Scope” یا &quot;جایی که به متغییر های دسترسی داریم&quot; همانگونه که به execution contexts فکر می کردیم فکر کنیم.یه سوال. Bar  در کد زیر چه چیزی در console  چاپ می کند ؟function foo () {
    varbar = &#039;Declared in foo&#039;;
}
foo();
console.log(bar)برسی میکنیم:هنگامی که foo  فراخوانی شد یک Execution Context روی Execution Stack ایجاد کردیم. در فاز ایجاد this و arguments  ایجاد شدند و مقدار bar  برابر undefined  قرار گرفت. بعد فاز اجرا اتفاق افتاد و متن Declared in foo در bar  قرار گرفت. بعد از آن فاز اجرا به پایان رسید و foo Execution Context از stack خارج شد. هنگامی که foo از Execution Stack پاک شد ما سعی کردیم که bar  را در console  چاپ کنیم. این مانند آن است که bar  کلا وجود ندارد در نتیجه undefined  میگیرم. چیزی که این به ما نشان می هد آن است که متغییر هایی که درون تابع قرار می گیرد به صورت محلی در آن وجود دارند. به این معنیست که (برای اکثر جاهااینگونه است  بعدا به حالت استثنا میخوریم) هنگامی که  Execution Context یک تابع از Execution Stack خارج شود دیگر به آن دسترسی نداریم..یه مثال دیگه:چه چیزی در console  چاپ می شود بعد از اینکه اجرای کد تمام شود؟function first () {
         var name = &#039;Jordyn&#039;
         console.log(name)
}
function second () {
var name = &#039;Jake&#039;
console.log(name)
}
console.log(name)
var name = &#039;Tyler&#039;
first()
second()
console.log(name)ما به ترتیب undefined، Jordyn،Jake، Tyler از چپ به راست خواهیم داشت. چیزی که به ما نشان می دهد آن است که شما می توانید به Execution Context به گونه ای فکر کنید که محیط متغییر منحصر به فرد خودش را دارد. اگرچه Execution Contextsهای دیگری هم هستند که شامل متغییر name هستند، اما موتور جاوااسکریپت ابتدا به current Execution Context برای آن متغییر نگاه میکند.که این سوالی را ایجاد میکند که چه می شود اگر متغییر درون Execution Context کنونی حضور نداشته باشد؟ آیا موتور جاوااسکریپت جستجو در مورد آن متغییر را متوقف می کند ؟ بگذارید مثالی ببینم که به این سوال پاسخ دهد. در کد زیر چه چیزی چاپ میشود ؟var name = &#039;Tyler&#039;
function logName () {
console.log(name)
}این پروسه از موتور جاوااسکریپت دونه به دونه جلو میره و هر Execution Context پدری را بررسی میکند تا ببنید متغییر در Execution Context محلی وجود دارد یا نه که به آن Scope Chain می گوییم. قبلا گفتیم که متغییر هایی که درون تابع تعریف می شوند در اکثر موارد بعد از اینکه Execution Context تابع از درون Execution Stack خارج شود دیگر به آن متغییر دسترسی نداریم اکنون موقع ان است که بگوییم چرا اکثر مواقع اینگونه است نه تمام مواقع. یک سناریو که در آن صدق نمی کند جایی است که شما تابعی درون تابع دیگر داشته باشید. در این مورد تابع درونی همچنان به scope تابع پدر یا بیرونی دست رسی دارد حتی زمانی که  Execution Context تابع بیرونی از  Execution Stack خارج شود.توجه کنید که بعد از آنکه makeAdder Execution Context از Execution Stack خارج شد Closure Scope ایجاد شد.درون Closure Scope متغییر هایی زیست میکنند که درون makeAdder Execution Context زیست میکردند. دیلیلش این است که ما تابعی درون تابع دیگر داریم. در مثال ما تابع درونی به شکل تو در تو درون تابع makeAdder  قرار گرفته است بنابراین تابع داخلی یک Closure  روی محیط زیست متغییر های makeAdder  ایجاد می کند. وقتی این محیط زیست از Execution Stack خارج میشود به خاطر وجود آن Closure  تابع داخلی به متغییر X  دسترسی دارد (توسط Scope Chain).همانطور که حدس میزنید این مفهوم که تابع فرزند  “closing” روی زیستگاه متغییر های تابع پدر را Closures می خوانند.</description>
                <category>ابوالفضل رضوانی نراقی</category>
                <author>ابوالفضل رضوانی نراقی</author>
                <pubDate>Mon, 13 Apr 2020 03:34:09 +0430</pubDate>
            </item>
                    <item>
                <title>فهمیدن ()bind(), apply() ,call در زبان Javascript</title>
                <link>https://virgool.io/@rezvani2647/%D9%81%D9%87%D9%85%DB%8C%D8%AF%D9%86-bind-apply-call-%D8%AF%D8%B1-%D8%B2%D8%A8%D8%A7%D9%86-javascript-hubmd573bpy5</link>
                <description>سلام، در اونجا یعنی مقاله قبلی قصد داشتم تا this keyword رو توضیح بدم. ولی در اینجا قصد خاصی ندارم گفتم دوره هم هستیم ببینیم اگر یه روز خواستیم به زور به یه function بگیم که this شما به چی ارجاع داده بشه باید چه کار کنیم ؟ خب javascript در این مواقع برای ما ۳ تا متد مرتب و مجلسی  فراهم کرده. به اسمایی که در تایتل میبینید.پیشنیاز : فهمیدن this keyword در javascriptاز call شروع میکنمبه کد زیر توجه کنید:const Person = {
       firstName: &amp;quotAmir&amp;quot,
       lastName:&amp;quotRezvani&amp;quot,
       printPerson: function () {
              console.log(this.firstName + &amp;quot &amp;quot +this.lastName);
       }
};

Persin.printPerson();   // ===&gt; &amp;quotAmir Rezvani&amp;quotخب مشخصه که برامون Amir Rezvani رو چاپ کرد حالا یه آبجکت دیگه کنارش اضافه میکنیم. اگر من بخوام printPerson رو با مقدار دیگه‌ای فراخوانی کنم، یعنی باید دوباره بنویسمش ؟ بعد برم داخل Object مقدار firstName و lastName رو تغییر بدم ؟ جواب اینه نه از call استفاده میکنیم. (حواستون باشه فرض کنید کد بالا رو کنار کد پایین نوشتیم جدا نیستن فقط نخواستم دوباره کد رو کپی کنم پایینم بنویسم).const Person2 = {
      firstName: &amp;quotArash&amp;quot,
      lastName:&amp;quotNaraqi&amp;quot,
};

Person.printPerson.call( Person2 ); // ===&gt; &amp;quotArash Naraqi&amp;quotحالا اتفاقی که افتاد اینه اول در متد printPerson ما نوشته بودیم  this.firstName + &quot; &quot; +this.lastName که this به Person رجوع میکرد. ولی وقتی بهش گفتیم که با آبجکت Person2 این تابع رو call کن . یعنی بهش گفتیم که this به Person2 اشاره کنه. در نتیجه this به Person2 رجوع می‌کنه.حالا اگر این تابع یه آرگومان داشته باشه چی اونو کجا باید بهش پاس بدیم ؟جواب اینه که آرگومان اول در call یعنی آبجکتی که this باید بهش ارجاع بده و  تمام آرگومان‌های باقی مانده رو میتونیم بعد از اون دونه دونه با ویلگول جدا کنیم و بهش پاس بدیم.یه مثال میزنم:const Person = {
        firstName: &amp;quotAmir&amp;quot,
        lastName:&amp;quotRezvani&amp;quot,
        printPerson: function (ALERT, NAME) {
                console.log(ALERT,NAME);
                console.log(this.firstName + &amp;quot &amp;quot +this.lastName);       
         }
 };

const Person2 = {       
        firstName: &amp;quotArash&amp;quot,
        lastName:&amp;quotNaraqi&amp;quot, 
};

Person.printPerson(&amp;quotSUCCESS&amp;quot,&amp;quotHello&amp;quot); 
///////////// output ///////////// 
// SUCCESS, Hello 
// Amir Rezvani
///////////// ///////////// ///////////// 

Person.printPerson.call( Person2 , &amp;quotSUCCESS&amp;quot, &amp;quotHello&amp;quot);
///////////// output ///////////// 
// SUCCESS, Hello 
// Arash Naraqi
///////////// ///////////// /////////////  بریم سراغ ()applyمتد apply دقیقا مثل call میمونه ولی فقط با یک تفاوت اونم اینه که میتونیم ارگومان هایی که قبلا با ویلگول جدا میکردیم و به تابع پاس میدادیم پشت هم درون یک آرایه بگذاریم و یه دفعه آرایه رو پاس بدیم که راحت‌تر باشیم.Person.printPerson.apply( Person2 , [&amp;quotSUCCESS&amp;quot, &amp;quotHello&amp;quot] ); 
///////////// output /////////////  
// SUCCESS, Hello 
 // Arash Naraqi 
///////////// ///////////// /////////////آخریشم bindداستان call و apply اینه که به محض فراخوانی‌ اجرا میشوند. اگر بخوایم ارجاع this رو برای تابعی مشخص کنیم ولی بعدا در کد اونو فراخوانی کنیم میتونیم از bind استفاده کنیم. همیچنین قابلیت‌های جالبی به ما میده که در مثال براتون توضیح میدم.به نظر خودم به سایت Mozilla حتما سر بزنید تا بهتر و دقیق‌تر بتونید یاد بگیرید.ولی درکل متد bind یک function جدید میسازه که وقتی فراخوانی میشه this اون برابر با همان مقداری هست که براش فراهم شده به‌علاوه با توالی مشخصی از آرگومانها که قبل از فراخوانی تابع جدید( این تابع جدیدی که ساخته) ارائه شده .const module = {
    x: 42,
    getX: function () {
        return this.x;
    }
};

const module2 = {
    x: 55,
}

const unboundGetX = module.getX;
console.log(unboundGetX());  // ==&gt; undefined

const unboundGetX = module.getX.bind(module2);
// ==&gt; 55از اونجایی که module.getX برابر با مقدار خود فانکشن هست درست مثل اینه که ما ()unboundGetX خارج از module فراخوانی کردیم و طبق مقاله قبلی this به window ارجاع پیدا می‌کنه و در window پروپرتیه x  نداریم. اما با استفاده از bind به unboundGetX اعلام میکنیم که this برابر با module2 است.جای دیگه که این متد بسیار خودشو قدرتمند نشون میده جاهایی مثل مثال زیره :function LateBloomer() {
  this.petalCount = 2;
  this.declare = function() {   
            console.log(&#039;I am a beautiful flower with &#039; +     this.petalCount + &#039; petals!&#039;); 
     };
}

LateBloomer.prototype.bloom = function() {
  setTimeout&#40;this.declare.bind(this&#41;, 1000);  // *
};
const flower = new LateBloomer();
flower.bloom();همانطور که می‌دونید setTimeOut متدی از window هست و this همیشه به window برمیگرده. در چنین مواقعی باید مشخصا اعلام کنیم که this چه مقداری باید داشته باشه فقط حواستون باشه که مقدار this خارج از setTimeout مشخص شده و  بعد this.declare.bind به عنوان function درون setTimeout قرار گرفته. این جوری مثل زیر ننوشتیمش:const x = this.declare.bind(this); // --&gt; (this) is just LateBloomer here in both this
setTimeout&#40;x, 1000&#41;;اگر مثل بالا باشد this به window برمیگرده. اگرم دوست داشتین اینجوری تعریفش کنید میتونید از روش cache کردن همونطور که در مقاله قبلی گفتم استفاده کنید. اینجا x در حقیقت بیرون setTimeOut قرار گرفته و مقدار this در هر دو جای استفاده شده در این خط this.declare.bind(this) دقیقا یک مقدار داره. و اونم داره به LateBloomer اشاره میکنه. اما وقتی bind نمی‌کنیم دقیقا مثل این میمونه که این کارو کرده باشیم. setTimeout&#40;this.declare, 1000&#41;;  
 ==
setTimeout&#40;function(&#41; {
     console.log(&#039;I am a beautiful flower with &#039; +     this.petalCount + &#039; petals!&#039;);      
 })و دقیقا در این حالت بدون اشاره مستقیم به this تابع فوق مقدار this پیش فرض در setTimeOut رو قرار میده که همون مقدار window هستش. یه جور دیگه بگم یعنی در this.declare مقدار this اول که به LateBloomer شاره میکنه خرج آوردن متد declare شده و this دوم هم که باز به LateBloomer اشاره میکنه خرج جای گذاری مقداره this با this پیش فرض setTimeout شده.خلاصه مطلب:متد های call و apply به امکان اینو میدن که بطور دستی مقدار this رو مشخص کنیم. فرقشون با هم اینه که در call آرگومان های ارسالی به تابع با ویرگول(،) از هم جدا میشن . ولی در apply کل آرگومان‌ها رو درون آرایه یه جا ارسال میکنیم.  و فورا فراخوانی میشن.متد bind هم مثل اونا کار میکنه ولی مقدار اونو میشه جایی ذخیره کرد و بعدا هر وقت که خواستیم فراخوانی کنیم.</description>
                <category>ابوالفضل رضوانی نراقی</category>
                <author>ابوالفضل رضوانی نراقی</author>
                <pubDate>Fri, 17 Jan 2020 23:49:14 +0330</pubDate>
            </item>
                    <item>
                <title>فهمیدن  this keyword در زبان Javascript</title>
                <link>https://virgool.io/@rezvani2647/%D9%81%D9%87%D9%85%DB%8C%D8%AF%D9%86-this-keyword-%D8%AF%D8%B1-%D8%B2%D8%A8%D8%A7%D9%86-javascript-l66l1gxgadci</link>
                <description>در این جا قصد دارم مفهوم this رو بیان کنم تا کسانی که هنوز کمی در استفاده از this مشکل دارن درک بهتری از اون پیدا کنن.خب به طور کلی مشکل اصلی با this همیشه اینه که this به چی اشاره داره؟ یا به عبارتی this به چی برمیگرده یا ارجاع پیدا میکنه؟خب this همیشه به آبجکت ای برمیگرده که در اون آبجکت یا در متد اون آبجکت در حال اجرا شدنه. یا به عبارتی میشه:The Object That Is Executing The Current Functionبرای اینکه بفهمیم کدوم آبجکت هم هست باید بدونیم اون تابعی که this در اون در حال اجرا شدنه از کجا و چگونه فراخوانی شده.خب اگر بیایم و در یک مرورگر console رو باز کنیم و فورا داخلش تایپ کنیم this و Enter بزنیم متوجه میشیم که به Window Object اشاره میکنه. حالا اگر کد زیر رو تایپ کنیم چی ؟function () {
    console.log(this)
}در این صورت باز هم به window object اشاره خواهد کرد. چون تمام توابع و متغییر ها زیر مجموعه این آبجکت سراسری هستند. نکته : اگر Strict Mode فعال باشه مقدار winodw object به undefined بر میگرده و بنابراین  در قسمت هایی که this به window object بر میگشت الان دیگه به undefined بر میگرده.خب حالا اگر کد زیر رو بزنیم نظرتون چیه ؟const myObj = {
    init: function () {
        console.log(this);
    },
    print: function(STP) {
        console.log(STP)
    }
}
myObj.init();           //  ----&gt; myObj
myObj.print(this)     // -----&gt; windowهمونطور که گفتم چون this در متد init داخل function ای هست که اون function متعلق به myObj هست. پس به myObj بر میگرده ولی در متد print مشاهده میکنیم که مقدار window رو برامون چاپ کرده دلیلش هم اینه که مقدار this داره وارد این متد میشه و  خارج از myObj مقدار دهی شده. this در بیرون این object به window اشاره میکرده پس الانم وقتی بیاد داخل این متد  باز هم به window اشاره خواهد کرد.حالا یه مثال دیگه از jQuery حتما شده که با استفاده از jQuery بخواین یه Click Listener برای یه button بنویسید. به مثال زیر دقت کنید. هر وقت که روی button پرینت کلیک کنید. مقدار this نمایش داده میشود.var printObj = {
    init: function () {
            const elem = $(&#039;button#print&#039;);
            elem.on(&#039;click&#039;, function (){
                     console.log(this); 
            }); 
      }
}
printObj.init();که در اینجا this مقدار button با آی دی print رو به ما نمایش میده ولی چرا ؟ چرا مقدار printObj رو به ما نشون نمیده چون اگر elem رو کنسول کنید متوجه میشید که elem یه Object هست و  تابع کلیک ما برای elem یک متد به حساب میاد و در واقع طبق تعریف اول ما this برای آبجکت elem هست نه برای printObj حالا اگر بخوایم که درون تابع click به printObj دست‌رسی پیدا کنیم میتونیم از تکنیک cache استفاده کنیم. به شکل زیر:var printObj = {
    init: function () {
    const self = this;
    const elem = $(&#039;button#print&#039;);
            elem.on(&#039;click&#039;, function (){
                      console.log(self);
            })
      }
   }
   printObj.init();در اینجا self به ما printObj رو نشون میده.خب تا اینجا متوجه شدیم که اگر this درون متدی  از یک آبجت باشه به همون آبجکت برمیگرده و اگر خارج از اون آبجکت باشه به در حقیقت درون یک function باشه که این function هم متد هیچ آبجکتی نباشه پس به window برمیگرده یا اگر NodeJs باشه به global برمیگرده.function amir (name) {
    console.log(this) // ---&gt; window obj
    this.name = name
}

const Modal = {
        init: function () {
                console.log(this) // ----&gt; Modal Obj
        },
}یه پله پیچیده تر:یه آبجکت تعریف میکنم که پروپرتی store داره و یک لیست از کالا به همراه تابعی که لیست این کالا ها رو چاپ میکنه. اگر متد print رو فراخوانی کنم میشه به شکل زیر:const Basket = {
        store: &amp;quotHasan Agha&amp;quot,
        list: [&amp;quotApple&amp;quot, &amp;quotPen&amp;quot, &amp;quotApple pen&amp;quot],
        print: function () {
                this.list.forEach(function (item) {
                        console.log(item);
                })
        }
};

Basket.print();

/* ------------------  */
Apple
Pen
Apple pen
تا اینجا که مشکلی نیست ...خب حالا چی میشه اگر بخوام اسم مغازه هم کنار این کالا ها قرار بدم حتما میگین خب کاری نداره this  رو که داریم میریم اونجا که داره  لوپ میزنه تا چاپ کنه this.store رو اضافه میکنیم اینجوری ..this.list.forEach(function (item) {                         
        console.log( this.store --  item);                 
});
/* ------------------  */
undefind -- Apple 
undefind -- Pen 
undefind -- Apple penخب this.store که باید &quot;Hasan Agha&quot; رو نشون میداد داره undefind نشون میده اذیت میکنه.خب پنیک نزنید داستان اینه  forEach رو شما تعریف نکردید درسته ؟ از کجا اومده از متغییر سراسری window و باید this اش به window اشاره کنه دیگه. دروغ میگم بگو دروغ میگی دعوا که نداریم. حالا دوست داری دقیق تر بدونی جریان چیه ادامه بده این پاراگراف رو ...  و علت اینکه من می تونم ازش استفاده کنم بر میگرده به خاصیت chaining زبان جاوا اسکریپت. یکم با من باشید تا بگم: بینید js میگه این متدی که فراخونی کردی در این آبجکتی که توش هست وجود داره یا نه اگر داشت استفاده میکنه اگر نداشت میری آبجکت پدرش و دوباره همین داستان رو چک میکنه داشت داشت نداشت پدرش تا میره میره میرسه به window پس این توابعی که در آبجکت window هستند در واقع همه جا قابل استفاده هستند. setTimeout هم جز همین داستانه (این بابا اصلا تو زبان js هم نیست موتور مرورگرتون داره اضافش می‌کنه) حالا نکته چیه نکته اینه که js درواقع یه سری توابع خاص برای هر دسته از تایپ های خودش تعریف کرده (البته js تایپ safe نیست که نمیخوام بحثش الان باز بشه)  داره برای مثال برای  تایپ آرایه forEach داره یا .length داره پس هر چیزی که به عنوان آرایه تعریف میشه تمام خصوصیتها یا به عبارتی تمام متد های تایپ آرایه  رو در خودش ارث بری میکنه و بهشون دست رسی داره بنابراین من اگر this.List رو به عنوان آرایه تعریف کنم  در نتیجش به forEach دست رسی دارم. و چون forEach برای window هستش و this.store منم داخل forEach هستش این میشه که this به window اشاره میکنه نه به Basket و با خاصیت chaining میره تا به window میرسه.حالا یه مثال جالب انگیزناک  :اگر this درون یک Constructor Function باشه چی ؟function Amir() {
        this.name = &amp;quotAmir&amp;quot
        this.printName = {
                console.log(this.name)
        }
};
Amir.printName();    //   ---&gt; Uncaught TypeError: Hasan.printName is not a function
const A1 = new Amir();
A1.printName();         //   ----&gt; Amirحتما میپرسید که مگه نگفتی اگر فانکشن من داخل متد نبود به window بر میگرده پس چرا الان باز به Amir برگشت؟جواب اینه که وقتی که از new استفاده میکنیم. پشت صحنه  javascript یک آبجکت خالی درست میکنه. و this رو به اون آبجکت خالی برمیگردونه.بنابراین printName حکم method و name حکم property رو برای A1 ایفا میکنه. البته فقط وقتی که از کلمه رزرو new استفاده میکنم. در غیر این صورت همونطور که دیدید Uncaught TypeError برخوردیم. که بایدم میخوردیم اون Amir که نوشیتم تا new نکنیم به فانکش معمولیه پس this داره به window obj بر میگرده پس printName برای window obj ست شده نه برای Amir . بنابراین  window.printName();    // ---&gt; Amir
Amir.printName()         // --&gt; Uncaught TypeError: Hasan.printName is not a functionولی درست بعد از استفاده از new و ذخیره در A1 متوجه شدیم که داره به A1 برمیگرده.برای همینه که میگم باید دید this در کجا و چگونه داره فراخوانی میشه.  (اینجا فعلا همینو نگه دارین و بدونین چون بخوام روی این قسمت ریز بشم باید prototype and inheritance هم بگم که هدفم اینه در مقالات بعدی بگم )خلاصه اینها میشه این:اگر در function معمولی بود بر میگرده به windowاگر درون متد بود بر میگرده به اون آبجکتی که داره متد رو اجرا میکنهاگر درون constructor function بود بعد از new کردن برمیگرده به همون constructor function ولی قبل new همون function معمولی به حساب میاد.خب حالا یکمی عمیق تر میگم:زبان جاواسکریپت Run Time Compile هست یعنی همون لحظه که داره کامپایل میشه اجرا هم میشه در ضمن محیط یا اسکوپی که خط در حال اجرا در اون قرار داره بهش &quot;Execution Context&quot;&#x27; گفته میشه. و در ران تایم javascript یک پشته از این Execution Context ها داریم اون تکه کدی که در بالای این پشته قرار داره در حال اجرا شدنه و this همیشه در حال ارجاع دادن به اون تکه کده و هر بار که این تکه کد تغییر میکنه مقدار آدرس this هم باهاش تغییر میکنه.خب تا اینجا متوجه شدیم که چرا this همیشه در جای های مختلف مقادیر مختلفی رو به ما نشون میده.راههایی هم هست برای اینکه مشخصا ذکر کنیم this در تابع یا متد مورد نظر ما دقیقا چه مقداری به خودش اختصاص بده که اونم با استفاده از متد های call - apply - bind هست که در پست بعدی قصد دارم توضیح بدم.کلام آخر:امیدوارم به دردتون خورده باشه.و حتما این مثال هایی که زدم رو کار کنین. اگر از لحاظ نگارشی هم مشکل داشتین منو ببخشید سعی میکنم بهترش کنم ولی دوست داشتم خیلی معمولی و به زبان ساده توضیح داده باشم.</description>
                <category>ابوالفضل رضوانی نراقی</category>
                <author>ابوالفضل رضوانی نراقی</author>
                <pubDate>Tue, 10 Sep 2019 01:30:40 +0430</pubDate>
            </item>
            </channel>
</rss>