کلیدواژه ی this و constructor ها

19 آبان 1398
جاوا اسکریپت OOP: کلیدواژه ی this و constructor

جاوا اسکریپت OOP : کلیدواژه ی this و constructor

با سلام خدمت شما همراهان روکسو! در این مقاله و چند قسمت بعد آن قصد دارم برنامه نویسی شیء گرای جاوا اسکریپت یا جاوا اسکریپت OOP را بررسی کنم. در این سری کوتاه مقالات وارد مباحثی مانند کلیدواژه ی this و constructor ها، مفهوم Prototype، کلاس های ES6 و ... خواهیم شد بنابراین پیشنهاد می کنم که این چند مقاله را با دقت دنبال کنید.

در این قسمت مبحث اصلی ما کلیدواژه ی this و constructor ها در برنامه نویسی شیء گرا است. اگر با زبان های برنامه نویسی دیگر مانند Java یا PHP (بخش شیء گرای آن) یا #C و غیره آشنا باشید، مفهوم کلی this یا constructor را درک خواهید کرد (البته تفاوت هایی نیز وجود دارد).

برای مطالعه ی این مقالات باید با زبان جاوا اسکریپت در حد خوبی آشنا باشید بنابراین اگر با جاوا اسکریپت آشنا نیستید پیشنهاد می کنم به دوره ی آموزش جاوا اسکریپت ما سری بزنید.

حتما می دانید که Object literal ها چه هستند:

const Amir = {
    name: 'Amir',
    age: 24
}

کد بالا یک Object literal یا به طور خلاصه یک object است. کلمه ی literal یعنی خودمان به صورت دستی آن را تعریف کرده ایم و خصوصیاتش را نوشته ایم. ما می توانیم به راحتی به خصوصیات این شیء دسترسی داشته باشیم:

const Amir = {
    name: 'Amir',
    age: 24
}

console.log(Amir);

خروجی در console مرورگر:

شیء Amir در کنسول مرورگر
شیء Amir در کنسول مرورگر

همچنین اگر بخواهیم به خصوصیت خاصی دسترسی داشته باشیم می توانیم بدین شکل کد بنویسیم:

console.log(Amir.age);

خروجی در console مرورگر عدد 24 خواهد بود. تا اینجای کار همه چیز همان جاوا اسکریپت قدیمی خودمان است و مشکلی نداریم. اما تصور کنید که نخواهیم یک شیء را به صورت دستی بنویسیم. مثلا بخواهیم یک نقشه یا طرح کلی داشته باشیم تا بر اساس آن هر تعداد شیء که خواستیم، ایجاد کنیم. اگر بخواهیم تعداد زیادی شیء که زمینه ی مشترکی با هم دارند را ایجاد کنیم چطور؟ اگر بخواهیم اشیاء ای را به صورت پویا و اتوماتیک ایجاد کنیم چطور؟ با روش بالا نمی توان چنین کاری کرد چرا که باید هر شیء را به صورت دستی نوشت و البته نوشتن کدهای تکراری و زمان بر نیز از معایب آن محسوب می شود. اینجاست که constructor ها وارد می شوند!

ساختن یک constructor بسیار ساده است. برای شروع من یک تابع به نام Person (به معنی «فرد») می سازم:

function Person () {
    
}

نام این تابع را با حرف بزرگ P شروع کرده ام، چرا که بهتر است constructor ها با حرف بزرگ شروع شود. حالا کد زیر را به این تابع اضافه می کنم:

function Person () {
    this.name = 'Amir';
}

با نوشتن همین یک خط کد می توانیم یک شیء از این constructor را بسازیم. همانطور که می دانید اشیاء با کلیدواژه ی new ساخته می شوند بنابراین می گوییم:

function Person() {
    this.name = 'Amir';
}

const Amir = new Person();
console.log(Amir);

یعنی یک شیء جدید از constructor ای به نام Person ساخته شده و در ثابتی به نام Amir قرار گرفته است. ما این شیء را console.log کرده ایم:

نتیجه ی constructor
نتیجه ی constructor

حالا می توانیم هر تعداد شیء ای که خواستیم با استفاده از این constructor بسازیم:

const Amir = new Person();
const Erfan = new Person();
console.log(Erfan);

با مراجعه به مرورگر می بینیم که:

پویا کردن constructor
پویا کردن constructor

توجه داشته باشید که من Erfan را console.log کرده ام اما هنوز Amir نمایش داده می شود. چرا؟ به دلیل اینکه Erfan فقط نام متغیر است و نام شیء را در تعریف تابع constructor به صورت دستی Amir گذاشته ایم:

function Person() {
    this.name = 'Amir';
}

هیچکس constructor ها را اینطور نمی نویسد و قصد من فقط آشنایی شما با نکات ظریف آن ها بود. برای حل این مشکل باید constructor بالا را به شکل زیر تغییر دهیم:

function Person(name) {
    this.name = name;
}

const Amir = new Person();

یعنی نام را به عنوان یک پارامتر از تابع می خواهیم. در حال حاضر اگر بالا را به شکل قبل اجرا کنیم به شیء ای با نام undefined یا تعریف نشده برمی خوریم. چرا؟ به دلیل اینکه تابع constructor ما یک نام می گیرد (پارامتر) و اگر این پارامتر را به آن پاس ندهیم مقداری وجود ندارد که بخواهد به جای name قرار دهد و نام undefined می شود.

از این به بعد می توان گفت:

function Person(name) {
    this.name = name;
}

const Amir = new Person('Amir');
const Erfan = new Person('Erfan');
console.log(Amir);
console.log(Erfan);

حالا اگر به خروجی مرورگر نگاهی بیندازیم دیگر فقط Amir نمایش داده نمی شود، بلکه شیء Erfan نیز حضور خواهد داشت.

بر اساس چیز هایی که دیدیم آیا می توانید حدس بزنید کلیدواژه ی this (به معنی «این») چه کاری انجام می دهد؟ به const های بالا (Amir و Erfan) یک «نمونه» یا instance گفته می شود. یعنی نمونه ای از یک نوع شیء (در اینجا، اشیائی که توسط Person ساخته می شوند) هستند. کلیدواژه ی this به هر کدام از این نمونه ها در زمان ساخت اشاره می کند؛ زمانی که می گوییم this.name یعنی وقتی کلیدواژه ی new را صدا زده و می خواهیم با این constructor یک شیء جدید بسازیم، this به همان شیء جدید در حال ساخت اشاره می کند. به زبان ساده تر this یعنی این شیء!

به طور مثال اگر کد constructor را به شکل زیر تغییر بدهم چه می شود؟

function Person(name) {
    this.name = name;
    console.log(this);
}

با این کار دیگر نیازی به دستورات console.log نداریم و هر زمان که شیء ای را با new ایجاد کنیم، به صورت خودکار آن را در console مرورگر نیز نمایش می دهیم. در واقع نمایش شیء در console بخشی از فرآیند ساخته شده اشیاء ما شده است.

سوال: اگر سوال: اگر this را خارج از constructor استفاده کنیم چه می شود؟ آیا به خطا می رسیم؟

پاسخ: خیر! This به شیء ای اشاره می کند که در scope آن قرار دارد.

کد زیر را در نظر بگیرید:

function Person(name) {
    this.name = name;
}

console.log(this);

این this به شیء window (شیء اصلی در scope سراسری) اشاره می کند:

شیء window در کنسول مرورگر
شیء window در کنسول مرورگر

حالا می توانیم constructor خود را کامل تر کنیم:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

const Amir = new Person('Amir', 24);
const Erfan = new Person('Erfan', 26);
console.log(Amir.age);

بنابراین به همان روش قبل می توانیم سن (age) را نیز به شیء ساخته شده اضافه کنیم. واضح است که نتیجه ی دستور console.log در کد بالا عدد 24 خواهد بود. من این مثال را عمدا اینقدر ساده انتخاب کردم تا ابتدا با کلیت این بحث آشنا شوید اما در قسمت های بعد وارد جزئیات بیشتری خواهیم شد و این constructor را تکمیل می کنیم.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری شی گرایی در جاوا اسکریپت توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Sajjad
16 فروردین 1399
خدا خیرتون بده استفاده کردیم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Moji
21 آبان 1398
چند وقت بود دنبال ایجور مقاله ها بودم که شما پست کردین خیلی عالی

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.