Mohammad Bohluli
Mohammad Bohluli
خواندن ۵ دقیقه·۸ ماه پیش

اندر احوالات جاوااسکریپت (قسمت پنجم)

javascript
javascript


آنچه گذشت :

توی این مقاله گفتیم Execution Context ما سه قسمت داره که دوتاشو (scoping و Variable environments ) رو مفصل توضیح دادیم

توی این قسمت به آخرین مبحث یعنی this میپردازیم و پرونده Execution Context رو میبندیم

یه جمله راجع به this میگم ، اگه اینجمله رو درک کنید قضیه this براتون بسته میشه(قول میدم🙂):

☝🏻 کلیدواژه this یک متغیر خاص هست که به ازای هر Execution Context ایجاد می شود یادته به ازای هر تابع که صدا زده میشد یک Execution Context داشتیم ؟؟؟ پس میشه نتیجه گرفت که کلمه this یک متغیر خاص هست که به ازای هر تابع ایجاد می شود پس کلیدواژه this به صاحب تابع اشاره میکنه (این جمله خیلی خیلی مهمه) یا در اصطلاح میگن binding

☝🏻حواست باشه this به خود تابع اشاره نمیکنه هااا بلکه به صاحب اون تابع(یا method) اشاره میکنه

حالا که مفهوم this رو درک کردین بریم عمیق تر بشیم ببینیم this توی حالت های متفاوت چکار میکنه

1️⃣ کلیدواژه this در توابع :

توی یه تابع عادی که توی فضای گلوبال تعریف میکنیم :

اگه بدون strict mode اجراش کنیم صاحبش میشه کی ؟؟؟ آفرین، میشه آبجکت window

گفتیم this به صاحب تابع اشاره میکنه پس اینجا صاحب تابع showThis میشه آبجکت گلوبال window (البته توی مرورگر نه nodejs، توی رانتایم نود this به آبجکت گلوبال اشاره میکنه برو مقاله اول رو بخون)

اگه با strict mode اجراش کنیم چی ؟؟؟ جواب میشه undefined (همیشه سعی کنید مود strict فعال باشه)

'use strict'; function showThis(){ console.log(this); }; showThis(); 👉🏻 undifined -------------------------------------------------------------------------------------------- function showThis(){ console.log(this); }; showThis(); 👉🏻 window object

2️⃣ کلیدواژه this توی method ها :

توی متد ها اون آبجکتی که متد مورد نظر رو صدا زده میشه صاحب this ما

دوباره برمیگردیم به اون جمله ای که اول گفتم، صاحب متد کیه (یا کی اون متد رو صدا زده)؟؟؟ آبجکت Person پس مقدار (یا صاحب) this میشه Person

const Person = { firstName: 'Reza', lastName: 'Rezai', age: 1990, calculateAge() { return 2024 - this.age; }, }; console.log(Person.calculateAge()); 👉🏻 34

در واقع return 2024 – this.age توی پس قضیه اینطوری میشه return 2024 – person.age

3️⃣ کلیدواژه this توی Event Listener ها :

توی این مورد this ما اشاره میکنه به اون المنتی که EventListener روش صدا زده شده

یعنی صاحب this ما توی مثال المنت Button هس

button.addEventListener( ' click ' , function () { console.log(this); });

4️⃣ کلیدواژه this توی Arrow Function ها :

اینجا دیگه جریان فرق میکنه، این نوع توابع this ندارند یا بهتره بگم this مربوط به خودشونو ندارن

پس چطور میشه ؟؟؟طبق گفته سایت MDN این توابع this عه نزدیکترین زمینه (context) یا اسکوپی که تابع توش تعریف شده رو میگیرن

در اصلاح میگن این توابع دارای lexical this هستن به این معنی که مقدار this آنها توسط محدوده اطرافشان (surrounding) تعیین می شود

به زبون عامیانه تر توی این نوع توابع thisعه والد رو میگیره

کد زیر گویای همه چیزه

# regular function 'use strict'; function showThis(){ console.log(this); }; showThis(); 👉🏻 undifined ---------------------------------------------------------- # arrow function 'use strict'; const showThis = () => { console.log(this); }; showThis(); 👉🏻 window object

همون طور که کد بالا قسمت arrow function رو میبینید چون this خودش رو نداره پس میره به context ایی که توش هست یا اسکوپی که توش هست (همون والدش) میگه :

دستم به this ات ، این this تو بده ما استفاده بکنیم، والدش هم که آبجکت گلوبال window هست this اش رو میده دستش

مثال دوم رو هم میزنیم که بری و راضی باشی:

window.myName = 'mohammad'; const user = { myName : 'ali', hello: () => { return 'Hello ' + this.myName ; }, }; console.log(user.hello()); 👉🏻 Hello mohammad

توی کد بالا ما دوتا آبجکت داریم که پراپرتی myName رو دارن یعنی window (که آبجکت گلوبال) و user

خب چون متد ما از نوع arrow function هستش میاد this والد یا نزدیکترین اسکوپ که حاوی myName هست رو میگیره و نمایش میده یعنی myName که صاحبش آبجکت گلوبال window هست

در واقع اصلا به آبجکت user نگاه هم نمیندازه 😞

حالا اگه همین متد رو با تابع regular بنویسی میاد ali رو برات چاپ میکنه (خودتون تست بزنید)

☝🏻اگه میخوایی برای آبجکتت متد بنویسی سعی کن از arrow function استفاده نکنی

❗اگه براتون سوال پیش اومده که چرا به جای اون window.myName = mohammad ننوشتیم const myName = mohammad به این علته که ما میخواییم اون myName پراپرتی عه آبجکت window باشه تا arrow function وقتی میره اسکوپ بالاترش رو جست و جو میکنه اونو پیدا کنه

پس اگه با const تعریفش کنیم جز پراپرتی های آبجکت window نیست و فقط یه متغیره معمولیه و undefined خروجی میشه چون تابع arrow هرچی گشته چیزی برای this پیدا نکرده بنده خدا 🙂

خب حالا فرض کنید ما خودمون میخواییم تعیین کنیم که چه متدی به کدوم آبجکت متصل بشه و this اش رو بگیره، اینجاست که سه تفنگدار به اسم bind و call و apply وارد بازی میشن

با این سه تا ما میتونیم صاحب this رو دستکاری کنیم و خودمون تعیین کنیم چی باشه

من توی این مقاله فقط به bind میپردازم چون کاربردی تره ولی اون دوتام تقریبا با تفاوت کم عین همینن ولی کلا مفهومشون با bind یکیه.

متد bindتابعی درست می‌کنه که مقدار this توی اون به یک آبجکت مشخص و تعیین‌شده‌ای اشاره می‌کنه که ما براش تعیین کردیم پس این تابع (یعنی تابعی که bind ساخته) همیشه به اون thisیی اشاره می‌کنه که ما براش تعیین کردیم

const yourNewMethod = yourMethod.bind(yourObject); yourNewMethod ()

برای اینکه یادتون بمونه به صورت عامیانه اینطوری به خاطر داشته باشید که اون yourMethod یه بازیکن فوتباله و bind هم یه دلال و yourObject هم یه تیم فوتبال 😁 حالا داستان رو گوش کن کاری میکنم هیچوقت یادت نره

بازیکن(yourMethod ) میاد پیش دلال(bind) میگه من میخوام یه تیم(yourObject) انتخاب کنم دلال(bind) میگه باشه تو یه تیم(yourObject) انتخاب کن تا من بچسبونمت (بایندت کنم) به اون تیم⚽

حالا بیا رو مثال :

const bazikon = function () { console.log(this.yourTeam); }; ---------------------------------------------------- const sepahan = { yourTeam: 'sepahan', }; ---------------------------------------------------- const esteghlal = { yourTeam: 'esteghlal', }; ---------------------------------------------------- window.yourTeam = 'Team Meli'; ---------------------------------------------------- const bindSepahan = bazikon.bind(sepahan); const bindEsteghlal = bazikon.bind(esteghlal); ---------------------------------------------------- bindSepahan(); bindEsteghlal();

واقعا فکر نکنم دیگه توضیح بخواد نه ؟؟؟

اگه نگرفتی چی شد توی کامنتا بگو بیشتر برات توضیح بدم

اگه خوشت اومد و دوست داشتی توی کانال تلگرامم عضو شو LearnByLearn@ مقاله های بعدی هم دیگه تحت عنوان اندراحوالات جاوااسکریپت منتشر نمیشن بلکه به اسم خود موضوع منتشر میشن

امیدوارم بدردت خرده باشه ❤️

arrow functionexecution contextthis در جاوااسکریپتglobal objectbind method
علاقمند به تکونولوژی و هرچی که بهش مربوطه، کانال تلگرام LearnByLearn@
شاید از این پست‌ها خوشتان بیاید