بررسی this در جاوااسکریپت

مطمئناً تا به حال، کلمه کلیدی this در جاوااسکریپت به گوشتان خورده است. درک این که نقش this چیست و عملکرد آن به چه شکل است، به دانشی اساسی در حوزه جاوااسکریپت نیاز دارد. به عبارت ساده‌تر، باید بگوییم که کلمه کلیدی this به شی یا object‌ای اشاره دارد که توسط جاوااسکریپت انتخاب و اجرا می‌شود.

 

var test = {
   number: 5,
   testFunction : function() {
      return this.number;
   },
};
console.log(test. testFunction ());
// expected output: 5

 

به کد بالا دقت کنید. در اینجا، نحوه فراخوانی تابع، مقدار this را مشخص می‌کند. البته این کار را نمی‌توان هنگام اجرا انجام داد. چرا که مقدار آن ممکن است در هر بار فراخوانی تابع، متفاوت باشد. قالب کدگذاری در ES5، متدی به نام bind() را برای تعیین مقدار this در تابع معرفی می‌کند. این متد بدون توجه به نحوه فراخوانی تابع عمل می‌کند. اما قالب کدگذاری ES6، برای این منظور arrow functions را معرفی می‌کند که با استفاده از این توابع دیگر نیازی به اتصال bind به this نیست.

Global Context

مثال زیر، در درک بیشتر عملکرد this در global context به شما کمک خواهد کرد:

 

function namePerson() {
    console.log(this.name);
}
var name = "Doug";
var obj1 = { name: "Buggati", cars: cars};
var obj2 = { name: "Lamborgini", cars :cars};
namePerson();     // "Doug"
obj1.cars();      // "Buggati"
obj2.cars();      // "Lamborgini"

 

در کد بالا، تابع namePerson() در حال چاپ this.name است. به عبارت دیگر، این تابع در حال تلاش برای یافتن و چاپ مقدار name در خروجی است. اما در داخل تابع متغیری با این نام را پیدا نمی‌کند. پس به global context مراجعه می‌کند. در آنجا یک متغیر با نام name وجود دارد که مقدار آن “Doug” است. پس بدون درنگ، عبارت Doug را در خروجی چاپ می‌کند. 

سپس با فراخوانی obj1.cars() عبارت Buggati چاپ می‌شود. دلیل این امر این است که تابع cars() به همراه execution context که obj1 نام دارد، فراخوانی می‌شود. در واقع در اینجا this.name همان obj1.name است.

به همین ترتیب، به هنگام فراخوانی obj2.cars() عبارت Lamborgini چاپ می‌شود. زیرا execution context در تابع cars() با عنوان obj2 وجود دارد.

به حالت کلی، کلمه کلیدی this به global objectای اشاره دارد که پیش‌فرض در نظر گرفته می‌شود. در فراخوانی متدهایی که تابع داخل متغیر است، this به متدی اشاره دارد که object را فراخوانی می‌کند. بنابراین، فراخوانی تابع، مقدار this را تعیین می‌کند.

Function context

در یک تابع، مقدار this به فراخوانی تابع بستگی دارد. به مثال زیر توجه کنید تا بیشتر در این باره با هم صحبت کنیم:

 

function f1() {
   return this;
}
// In a browser:
f1() === window;
// true  // In Node:
f1() === global; // true

 

اگر کد بالا را در مرورگرتان اجرا کنید و مقدار تابع f1() را window قرار دهید، مشاهده می‌کنید که عبارت true در خروجی چاپ می‌شود. در واقع در اینجا this به مقدار تابع f1() بستگی دارد که پس از فراخوانی مشخص می‌شود. به همین ترتیب، اگر مقدار f1() را در Node بر روی global ست کنید، می‌بینید که باز هم عبارت true را چاپ می‌کند. 

حال اگر عبارت return this را ننویسیم چه اتفاقی می‌افتد؟ امتحان می‌کنیم.

 

function f2() {
'use strict';
// see strict mode  return this;
}
f2() === undefined; // true

 

باز هم در خروجی عبارت true چاپ شد. البته در صورتی که از use stric استفاده کنیم. به این حالت، strict mode گفته می‌شود. در strict mode، اگر execution context کلمه کلیدی this را تعریف نکند، مقدار آن نامشخص باقی می‌ماند.

Constructor Context

سازنده، تابعی است که بلافاصله به هنگام اجرای پروژه فراخوانی می‌شود. هنگامی که یک تابع به عنوان سازنده مورد استفاده قرار می‌گیرد، this به object ای اشاره دارد که به تازگی ساخته شده است. البته توجه داشته باشید که این سازنده به همراه کلمه کلیدی new نوشته می‌شود.

به مثال زیر توجه کنید تا درک این موضوع برایتان آسان‌تر شود:

 

function varX() {
   this.x = 003;
}
var number = new varX();
console.log(number.x); // 003
    function varY() {
      this.y = 003;
    return { y: 0003 };
    }
var number2 = new varY();
console.log(number2.y); // 0003

 

در اینجا، سازنده به تابعی با نام varX() اتلاق شده است. این سازنده، در متغیر number فراخوانی می‌شود. سپس هنگامی که number.x صدا زده می‌شود، ابتدا به متغیر number سری می‌زند و تابع varX() را مشاهده می‌کند. پس به داخل این تابع می‌رود و مقدار x را پیدا می‌کند. در نهایت عدد ۰۰۳ را چاپ می‌کند. همین روند برای دومین سازنده با نام varY() هم صادق است.

DOM event handler Context

زمانی که یک تابع به عنوان یک event handler مورد استفاده قرار می‌گیرد، this به عنصری که خروجی event است، اشاره داد. 

به مثال زیر توجه کنید:

 

// When called as a listener, turns the related element black
function turnBlack(event){ 
    // Always true  console.log(this === event.currentTarget);
    // true when currentTarget and target are the same object s
    console.log(this === event.target);
    this.style.backgroundColor = '#000000’;
}
    // Get a list of every element in the document
    var elements = document.getElementsByTagName('*');
    // Add turn Black as a click listener so when the// element is clicked on, it turns Black
for (var i = 0; i < elements.length; i++){
    elements[i].addEventListener('click', turnBlack, false);
}

 

نتیجه گیری

امروزه اکثر فریم‌ورک‌هایی که در جاوااسکریپت وجود دارند، از متغیر this استفاده می‌کنند. به عنوان مثال AngularJS، Vue، ReactJS و غیره. شیوه استفاده از آن ممکن است در فریم‌ورک‌های مختلف، متفاوت باشد. اما عملکرد آن در همه جا یکسان است. 

ابتدایی‌ترین مفهومی که می‌توان از متغیر this به دست آورد، این است که به شما این امکان را می‌دهد که به متغیرها و متدهایی که به صورت globally یا locally تعریف شده‌اند، دسترسی داشته باشید. همچنین، امکان فراخوانی ماژول‌ها یا پلاگین‌های مختلف را از جای جای یک حوزه خاص فراهم می‌کند. 

با تمام این اوصاف، استفاده از this بسیار ساده و کارآمد است. همین طور درک آن برای یادگیری جاوااسکریپت ضروری می‌باشد.

 

[button class=”github-btn” href=”http://frontcast.ir/course/javascript-advanced”]دوره جامع و پیشرفته جاوااسکریپت[/button]

 

منبع

دیدگاه‌ها:

افزودن دیدگاه جدید