خلاصه مطالعات من درباره ی scope در جاوا اسکریپت

سلام بچهااا من امروز می خوام راجب scope بنویسم همه ی ما زمانی که برنامه نویسی با هر زبانی شروع کردیم یه قسمتی مفهوم scope بهمون گفتن ولی من می خوام امروز یکم با دیتیل بیشتر بگم همزمان با نوشتن این ویرگول خودمم دارم یاد می گیرم پس اگه مشکلی اشتباهی چیزی هست بهم بگید خوشحال میشیم:)Block Scopeبچها این کد ببینید حدس بزنید خروجی چی میشه؟راسی بچها من این جا از IIFE استفاده کردم که یکی از مهمترین مزایای استفاده از IFFE اینه با به وجود آوردن یک اسکوپ ، محتویاتی که داخل آن قرار میگیرد را کپسوله میکند و دیگر به صورت public برای دیگران قابل دسترس نیست و و علت این نامگذاری این است که function expression در هنگام تعریف بلافاصله صدا زده میشود :)hello(3);function hello(b){ c = b ;ث}تو مثال اول 0و1و2و9 و تو مثال دوم دوبار 4 پیرینت می کنهولی چرا؟ خارج از scope شون متغیرهای c , i هنوز میشناسه؟انگار بلاک ها توانایی ذخیره کردن متغیرها توی scope خودشونو ندارنینی جاوا اسکریپت خاصیت بلاک اسکوپ نداریم ایا ؟خوب توی es5 برای این که این خاصیت وجود داشته باشه حتما باید از scope متدها استفاده می کردیم ولی الان es6 امده همه می دونیم let , const امدن روی کار !!!همون جور که گفتم اصطلاحا به var میگن function scoped variableو به let , const میگن blocked scoped variableکه ینی می تونم مقدار توی خود scope نگه دارند بیایید مثال قبلو با let اجرا کنیم ببینیم چی میشهمی بینیم که بعد 0و1و2 به ما میگه که Uncaught ReferenceError: i is not definedخوب توی scope یه رابطه وجود داره این مربع ها رو اگه هر کدوم یه scope {} در نظر بگیریم (اینجا nested scope عه که میشه scope های تو در تو )مربع c به تموم scope های a,b دسترسی داره و درواقع الان مربع c میشه گفت child scope مربع a,bعهخوب تا اینجا را می دونیم اکثرا ولی a به متغیرهای scope های c,b دسترسی نداره!!!خوب بریم سراغ کد ببینیم جریان چیهExplicit Blockیه قابلیت جدید توی es6 عه که به ما اجازه میده بلاک کاستومایز خودمون بسازیم این قابلیت میاد و یه بلاک خام بدون هیچ قابلیتی در اختیار ما میزارعه و به ما این امکان میده که کدهامون به صورت قسمت قسمت بنویسیمبه کد زیر نگاه کنید باحاله:)خروجی خودتون ببنید:) درباره ی nested scope که بهتون گفتم scope c می تونست به متغیرهای scope a,b دسترسی داشته باشه حالا اگه نخواییم این دسترسی بدیم میایم و از Explicit Block استفاده می کنیممثلا اینجارو ببینید خوب اینجا خروجی شد 5 و 6 و Uncaught ReferenceError: someData is not definedفهمیدیم که Explicit Block مقدار b را عوض کرد و درواقع ذخیره کرد ولی نمی تونیم متغیرهایی که توی Explicit Block هستن استفاده کنیم و در دسترس child scope ها نیستن :) look-upکاری که scope داره می کنه ینی دنبال متغیرها میگردعه تا اون ها را مقدار دهی یا استفاده کنه بهش میگن look-up (این واژه های استفاده می کنه و مقداردهی اینا برا منم زیاد اشنا نبودن یه جوریه انگار:/ )دو مفهوم دیگهLeft Hand Side look-up : Go get the source of value and assign somthingRight Hang Side look-up : Go get the value of the identifier (variable or function)یه مثال دیگه یه چیز جالب چرا ref error نمیده اینجا؟خوب بچها بیایین به این کد نگاه کنیماین جا c تعریف نکردیم ولی کد بدون ارور اجرا میشه چرا واقعا؟!چون خود جاوا اسکریپت میاد و می گرده دنبال جایی که c تعریف شده می بینه عه نیست پس میاد خودش یه متغیر گلوبال ابجکت میسازه از c که توی همه ی scope ها قابل دسترسی میشهولی ممکن یه سریا حال نکنن اینجا از strict استفاده می کنیم که اگه این حالت پیش امد ref error بده به صورتی که اول کدمون 'use strict' اینو اضافه می کنیمتفاوت Lexical Scope , Dynamic Scopeبرنامه ها موقع اجرا به دو صورت عه compile time (همه ی کدها با هم کامپایل میشن و اگه خطا داشت خطی همون جا متوقف میشن) یا run time (خط به خط اجرا میشن)خوب Lexical scope در زمان compile time رخ میده و Dynamic Scope در زمان run time رخ میدهاز یه دید دیگه میشه گفت engine می خواد یه کدی اجرا کنه به هرچی که میرسه به متغیر به فانشن ( منظور همون RightHS و LeftHS ) از scope خودش می پرسه که اقا این چیه اونم بهش میگه مثلا این فانشن عه یا مثلا x مقدارش 2عهخوب حالا scope ها دو مدل دارند Lexical Scope , Dynamic Scopeبرای Lexical Scope مقداردهی اون متد مهمه (میاد توی foo و دنبال b میگرده و یه اسکوپ میره بالا)و برای Dynamic Scope کال شدن اون متد مهمه (توی همون long دنبال b می گردعه و به بیان دیگه اینجا خسته است تو اسکوپ خودش میگرده دنبال b)البته جاوا اسکریپت از dynamic ساپورت نمی کنه و صرفا مفهوم بود ولی بعضی زبان ها هر دو را ساپورت می کنن مثل perl روش دور زدن Lexical Scope در جاوا اسکریپتاین کار توصیه نمیشه چرا چون یه سری بهینه سازی هایی که توی موتور جاوا اسکریپت و خود خاصیت Lexical Scope هست از بین میرهولی برای کامل بودن این ویرگولم می نویسمشوناینجا فانکشن eval همون جور که نوشتم string به code تبدیل می کنهولی مشگلی که هست در زمان کامپایل یک بار b مقداردهی شده با دو و در زمان run time توسط فانکشن eval مجبوره دوباره یه چک دیگه بکنه که خوب توی پرفورمنس تاثیر زیادی میزارهHoistingیکی دیگر از مفهوم های js همین Hoisting هستندحدس بزنید چی چاپ میشه؟ممکنه فکر کنید undefined یا ارور میدهولی اینجا مقدار 2 چاپ میشه چرا ؟ چون در زمان کامپایل var b میره اول اول کدهامون قرار میگیرعهیه مثال دیگه این چی؟اینجا دیگه undefined چرا ؟چون مثل قبل میره بالا var b داستان ماولی مقدار دهی متغیرها در زمان ران تایم انجام میشه و در زمان ران تایم کدها خط به خط اجرا میشن و لاگ قبل از مقدار دهی هستهمین داستان توی فانکشن ها هم هستاین جا مشکلی نداره قبل declare کرد فانکشن مون call کردیم ولی می بینیم که type error میدعه چرا خوب؟چون var foo میره بالا وقتی خط بعدی کال میشه در زمان run time با مقدار هیچی call میشه و در واقع این جوری میشهمنبع ویدیوهای این کانال با اموزش علی یوسفی رمند هست که خیلی کمک به من کرد و می تونم بگم درواقع خلاصه ی این ویدیوها با یکم سرچ بیشتر براتون نوشتمراسی بچها می خواستم راجب closure ها بنویسم ولی دیدم اینجا خوب توضیح داده پس از همینجا بخونیم:)