تقریبا هر چیزی توی JS یک object به حساب میاد. حتی function ها و class ها هم در نهایت object هستن. در بسیاری از اوقات لازمه که به object جاری، یعنی object ای که داریم روش کار می کنیم اشاره کنیم. این جاست که کلیدواژه this مطرح میشه. در بقیه زبان ها هم کلیدواژه های مشابهی هست. مثلا در PHP از this$ استفاده میشه. در JS بر اساس جایی که کلیدواژه this رو استفاده میکنیم، به object های مختلفی اشاره میکنه. this درون یک class معنی متفاوتی داره در مقایسه با this داخل یک event. در ادامه مقاله به بررسی معانی مختلف this در JS می پردازیم.
میدونیم که JavaScript داخل مرورگر و یا با استفاده از node اجرا میشه و این محیط ها هم object های خودشون رو دارن. زمانی که this رو به صورت ساده داخل console مرورگر (واسه ورود به console می تونی F12 رو بزنی) تایپ میکنیم و enter میزنیم به ما آبجکت window رو بر می گردونه. window همون global object در مرورگر هاست. در node هم زمانی که this رو تایپ میکنیم به ما یک object بر می گردونه که همون global object محیط node هست.
console.log(this);
زمانی که داخل یک function کلیدواژه this رو استفاده میکنیم هم مجددا منظورمون global object هست. البته این تا زمانی درسته که از use strict استفاده نکرده باشیم. در حالت use strict مقدار this در یک تابع برابر با undefined خواهد بود.با توجه به معنی this داخل function ها دو تابع زیر عملکرد برابری با هم خواهند داشت:
function hello() { window.alert('hello'); } function hello() { this.alert('hello'); }
توابع سازنده، توابعی هستند که یک object رو میسازند و به صورت خودکار return اش میکنن. در خود JS چندین تابع سازنده داخلی داریم مثل String, Number و امثالهم. کلیدواژه this در توابع سازنده به معنی object ای هست که این توابع قصد ساختنش رو دارن. به کد زیر دقت کن:
// Construction function function Person(name){ this.name = name; } // Instantiating const user = new Person('bizhan'); console.log(user.name); // 'bizhan'
شاید برات سوال پیش بیاد که خوب بالاخره تابع سازنده هم یک تابعه. پس چرا معنی this در تابع سازنده با تابع ساده فرق داره؟! جواب اینه که وقتی از روی تابع سازنده میخایم یک شئ درست کنیم باید از کلیدواژه new (که تو کد بالا bold اش کردم) استفاده کنیم. این طوری JS متوجه میشه که این تابع یک تابع سازنده است و منظور از this در اون با توابع ساده فرق داره.
اول این مقاله ذکر کردیم که تقریبا هر چیزی در JS یک object حساب میشه. البته منظور از این object با object literal که با استفاده از { } اعلانش میکنیم دقیقا یکسان نیست. object الزاما به معنی object literal نیست و مفهوم خیلی وسیع تری داره. به مثال زیر دقت کن:
let age = new Number(26); console.log(typeof age); // 'object'
همون طوری که می بینی جنس age در کد بالا object عه. حالا به کد زیر دقت کن:
const user = { name: 'bizhan', age: 26 }; console.log(typeof user); // 'object'
مجددا در این کد هم جنس user برابر با object عه. پس متوجه شدی که برای درست کردن یک object الزامی به استفاده از { } نداریم. در JS در اکثر مواقع منظور ما از object متغیری هست که با استفاده از { } اعلان شده.
وقتی درون یک object (به عبارت دقیق تر درون یک object literal) از کلیدواژه this استفاده میکنیم، منظورمون خود اون object هست. به کد زیر دقت کن:
const user = { name: 'bizhan', family: 'hejazi', fullName: function() { return this.name + ' ' + this.family; } } console.log(user.fullName()); // 'bizhan hejazi'
در کد بالا متد (تابعی که متعلق به یک object باشه رو میگن متد) fullName برای تولید نام کامل user از کلیدواژه this استفاده میکنه. از اون جایی که this درون یک object به معنی خود اون object هست پس this.name یعنی نام کاربر.
از ورژن ES6 به بعد میتونیم با استفاده از کلیدواژه class مثل زبان های معروف دیگه در JavaScript هم class اعلان کنیم. البته این کلیدواژه صرفا میانبری برای Prototyping عه و در پشت صحنه هنوز هم از پروتوتایپ ها استفاده میشه (واسه مطالعه بیشتر درباره پروتوتایپ ها این مقاله رو بخون). درون یک class کلیدواژه this به معنای object ای خواهد بود که قراره از روی این کلاس درست بشه. به کد زیر دقت کن:
class Person { constructor(name, family) { this.name = name; this.family = family; } fullName() { return this.name + ' ' + this.family; } } const user = new Person('bizhan','hejazi'); console.log(user.fullName()); // 'bizhan hejazi'
در یک event معنی this آبجکتی هست که event رو دریافت کرده. برای درک بهتر این مورد به کد زیر دقت کن:
<button ="console.log(this)">Click on Me</button>
در کد بالا منظور از this عنصر button هست. با استفاده از this در event ها می تونیم همون عنصری که روش کلیک شده (یا هر event دیگری) رو به عنوان یک object درون JS دریافت کنیم و اعمال مد نظرمون رو روش انجام بدیم. مثلا در کد بالا می شد عنصری که روش کلیک شده رو پنهان کرد یا مثلا رنگ پس زمینه اش رو عوض کرد و غیره.
انعطاف پذیری JS در همه گوشه و کنار این زبان قابل لمسه. در مورد کلیدواژه this هم این نکته کاملا ملموسه. حالا که با this آشنا شدی بهتره بدونی که متد هایی مثل call, apply و bind می تونن معنی this رو برای یک متد عوض کنن. این طوری می تونیم از متد یک object روی object دیگری استفاده کنیم تا از دوباره نویسی کد خودداری بشه. در حوصله این مقاله نیست که این ۳ متد رو توضیح بده ولی بد نیست که در موردشون یک مطالعه داشته باشی.