چگونه با کلاس ها در Typescript کار کنیم؟

جمعه 5 مرداد 1397

اگر ما درحال توسعه ی هر اپلیکیشنی با Typescript هستیم چه در سطح بزرگ و چه در سطح کوچک باشد از کلاس ها برای مدیریت صفات و متدها استفاده خواهیم کرد بنابراین در این مقاله نحوه ی کار با کلاس ها در Typescript را توضیح خواهیم داد.

چگونه با کلاس ها در Typescript کار کنیم؟

قبل تر ها در JavaScript ES5 مفهومی از کلاس ها نداشتیم و از توابع برای ساخت رفتارهایی مانند کلاس استفاده می کردیم. TypeScript کلاس ها را به عنوان بخشی از نسخه ی اولیه ی خود معرفی کرد و حال ما کلاس ها را در ES6 نیز داریم.

رفتار کلاس ها در TypeScript و JavaScript ES6 بسیار مشابه رفتار زبان های شئ گرا نظیر C# یا غیره که خودتان استفاده می کنید می باشد.

این مقاله از کتاب TypeScript 2.x نوشته شده توسط Sachin Ohri گرفته شده است.

برنامه نویسی شئ گرا در TypeScript

برنامه نویسی شئ گرا به ما اجازه می دهد تا کد خود را به صورت اشیاء ، که خود اشیاء نمونه هایی از کلاس هستند که صفات و متد ها را نگه داری می کنند، نشان دهیم. درواقع کلاس ها ظرفی برای صفات و رفتار ها هستند. مدل کردن کد به شکل کلاس ها به ما اجازه می دهد تا به ویژگی های متنوعی از برنامه نویسی شئ گرا که به ما اجازه ی نوشتن کد های بصری تر، با قابلیت استفاده ی مجدد و قوی تر را می دهد، دسترسی داشته باشیم. ویژگی هایی نظیر کپسوله سازی، چندریختی و وراثت نتایج پیاده سازی کلاس ها هستند.

TypeScript با پیاده سازی کلاس ها و interface ها به ما امکان نوشتن کد به سبک شئ گرا را می دهد. این ویژگی باعث می شود توسعه دهندگانی که از زبان های سنتی مثل جاوا و C# شروع به یادگیری این زبان می کنند احساس راحتی کنند.

فهم کلاس ها

قبل تر ها در جاوااسکریپت ES 2015 توسعه دهندگان مفهومی به نام کلاس نداشتند و بهترین راهی که می توانستند جایگزین رفتار کلاس ها کنند توابع بود. توابع مکانیسمی به گروهی از صفات و متد های مرتبط به یکدیگر می دهد. متد ها، هم می توانند به صورت داخلی به توابع اضافه شوند و هم می توانند با کلمه ی کلیدی prototype اضافه شوند. قطعه کد زیر مثالی از چنین توابعی است:

function Name (firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.fullName = function() {
  return this.firstName + ' ' + this.lastName ;
  };
}

در مثال قبلی تابع fullName در تابع Name کپسوله سازی شده است. راه دیگر اضافه کردن توابع با کلمه ی کلیدی prototype می باشد که در کد زیر نشان داده شده است:

function Name (firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}
Name.prototype.fullName = function() {
  return this.firstName + ' ' + this.lastName ;
};

این ویژگی های توابع بسیاری از مشکلات نداشتن کلاس را حل می کند اما بسیاری از جامعه ی توسعه دهندگان با این دیدگاه راحت نیستند.

کلاس ها این روند را ساده تر می کنند. کلاس ها یک انتزاع علاوه بر رفتار های معمول ارائه می کند بنابراین کد را قابل استفاده ی مجدد می کند. در ادامه syntax تعریف کلاس در TypeScript را داریم:

Syntax کلاس برای خوانندگانی که پیش زمینه ی شئ گرایی را دارند باید بسیار آشنا باشد. برای تعریف یک کلاس از کلمه ی کلیدی class که بعد از آن نام کلاس نوشته می شود استفاده می کنیم. کلاس News سه صفت و یک متد دارد به هر عضو یک نوع اختصاص داده شده است و همچنین یک سطح دسترسی برای مشخص کردن محدوده ی دسترسی نیز دارد. در خط 10 یک شئ از کلاس با کلمه ی کلیدی new ساخته ایم. کلاس ها در TypeScript مفهومی به نام constructor (سازنده) نیز دارند که می توانیم برخی از صفات را در همان زمان ساخت شئ مقدار دهی کنیم.

سطح دسترسی

زمانی که شئ ساخته می شود می توانیم به اعضای public کلاس با عمگر نقطه دسترسی داشته باشیم. توجه داشته باشید که نمی توانیم به صفات author با شئ espn دسترسی داشته باشیم زیرا این صفت private تعریف شده است . TypeScript سه سطح دسترسی ارائه می دهد:

Public

هر صفتی که با کلمه ی کلیدی public تعریف شود خارج از کلاس آزادانه قابل دسترسی است. همانطور که در مثال قبل دیدیم همه ی متغیر هایی که با کلمه ی کلیدی public تعریف شده اند خارج از کلاس در یک شئ دردسترس بودند. توجه کنید که اگر ما هیچ سطح دسترسی را مشخص نکنیم TypeScript ، public را به عنوان سطح دسترسی پیش فرض درنظر می گیرد این موضوع دلیل این است که در جاوااسکریپت همه چیز بطور پیش فرض public است.

Private

وقتی یک صفت به عنوان Private درنظر گرفته می شود خارج از کلاس قابل دسترسی نیست. زمانی که از TypeScript استفاده می کنیم محدوده ی دسترسی به متغیر های Private تنها در خود کلاس است. از آنجایی که در جاوااسکریپت سطح دسترسی نداریم با اعضای private همانند اعضای public برخورد می شود.

 Protected

عملکرد کلمه ی کلیدی Protected همانند private است با این تفاوت که متغیر های Protected در کلاس های مشتق شده نیز دردسترس است. کد زیر یک نمونه از چنین مثالی است:

class base{
  protected id: number;
}
class child extends base{
  name: string;
  details():string{
  return `${name} has id: ${this.id}`
  }
}

در کد قبل کلاس فرزند را برپایه ی کلاس والد گسترش داده ایم و به صفت id در کلاس فرزند دسترسی داریم. اگر یک شئ از کلاس فرزند بسازیم باز هم به صفت id از بیرون دسترسی نداریم.

Readonly

همانطور که از نام این سطح دسترسی پیداست پس از اینکه به صفتی با سطح دسترسی Readonly مقداری را نسبت دادیم دیگر قابل تغییر نیست. به یک صفت readonly فقط در زمان ساخت متغیر یا در سازنده می توان یک مقدار نسبت داد.

در کد بالا در خط 5 یک خطا داریم که می گوید صفت readonly است و نمی توان مقداری برای آن تعیین کرد.

ترجمه ی جاوااسکریپت از کلاس ها

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

TypeScript یک گزینه برای پیاده سازی جاوااسکریپت بر پایه ی استاندارد های ECMA ارائه می دهد. شما می توانید با استفاده از پرچم target  در فایل tsconfig.json ، TypeScript را برای ترجمه به جاوااسکریپت ES5 یا ES6 (ES 2015) و حتی ES3 پیکربندی کنید. بزرگترین تفاوت بین ES5 و ES6 مربوط به کلمات کلیدی class ، let و const است که در ES6 معرفی شدند.

اگرچه ES6 بیش از یک سال است که معرفی شده است اما هنوز بیشتر مرورگر ها بطور کامل از ES6 پشتیبانی نمی کنند بنابراین اگر شما درحال ساخت اپلیکیشنی هستید که مرورگر های قدیمی را هدف قرار می دهد ES5 را به عنوان هدف درنظر بگیرید.

بنابراین جاوااسکریپتی که پیاده می شود براساس تنظیمات هدف متفاوت خواهد بود در اینجا مثالی از کلاس در TypeScript خواهیم داشت و جاوااسکریپت را هم برای ES5 و هم برای ES6 تولید خواهیم کرد. کد زیر تعریف کلاس در TypeScript است:

این همان کدی است که در قسمت فهم کلاس ها معرفی کردیم. در این جا یک کلاس به نام News داریم که سه عضو دارد که دو عضو public و یک عضو private است. کلاس News یک متد format نیز دارد که دنباله ای از رشته ها را از متغیر های اعضاء برمی گرداند.

سپس یک شیئ از کلاس News در خط 10 می سازیم و به صفات public مقادیر را نسبت می دهیم. در خط آخر متد format را برای چاپ نتیجه فراخوانی می کنیم.

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

ES6 JavaScript

ES6 JavaScript به عنوان ES 2015 نیز شناخته می شود که آخرین نسخه ی جاوااسکریپت می باشد و بسیاری ویژگی های جدید را به ES5 اضافه کرده است. کلاس ها یکی از این ویژگی ها هستند در جاوااسکریپت قبل از ES6 کلاس ها را نداشتیم. کد زیر از کلاس های TypeScript که قبلا دیده ایم ساخته شده است:

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

در جاوااسکریپت مفهومی برای تعریف اعضای public نداریم متغیر های author  که private تعریف شده اند و در همان زمان تعریف مقداردهی شده اند به یک مقداردهی در سازنده ی جاوااسکریپت تبدیل شده اند. اگر ما author را مقداردهی اولیه نکرده باشیم جاوااسکریپت تولید شده، author را به سازنده اضافه نخواهد کرد.

ES5 JavaScript

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

زمانی که ما در گزینه های کامپایلر TypeScript ، ES5 را به عنوان هدف انتخاب می کنیم ، کد زیر تولید می شود:

همانطور که قبلا گفتیم تفاوت اصلی این است که کلاس ها به توابع تبدیل می شوند. جنبه ی جالب این تبدیل این است که کلاس News به یک IIFE تبدیل می شود. همانطور که در خط 9 قطعه کد قبل می توانیم ببینیم، یک IIFE می تواند با پرانتز در انتهای تعریف توابع مشخص شود. IIFEها باعث می شوند که تابع سریعا اجرا شود و نسبت به تعریف سراسری تابع به دستیابی محدوده ی صحیح تابع کمک می کند. تفاوت دیگر نحوه ی تعریف متد format  در ES5 JavaScript می باشد. همانطور که اینجا می توانیم ببینیم کلمه ی کلیدی prototype برای اضافه کردن رفتار های اضافه به تابع استفاده می شود.

ممکن است متوجه برخی تغییرات دیگر، نظیر تغییر کلمه ی کلیدی let به var ، زیرا let در ES5 پشتیبانی نمی شود، و غیره نیز شده باشید. همه ی متغیر ها در ES5 با کلمه ی کلیدی var تعریف می شوند و همچنین اینجا متد format برای چاپ خروجی از رشته ی template استفاده نمی کند بلکه از دنباله ی رشته های استاندارد استفاده می کند.

TypeScript با تبدیل کد به جاوااسکریپت با شیوه های توصیه شده امکان خوبی را می دهد. این کار به شما این اطمینان را می دهد که کدی قوی با قابلیت استفاده ی مجدد و با کمترین موارد خطا را دارید.

اگر این آموزش برای شما مفید بود حتما کتاب TypeScript 2.x By Example را برای آموزش های بیشتر درباره ی نحوه ی استفاده از قدرت TypeScript برای توسعه ی وب اپلیکیشن ها، بررسی کنید.

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

تاکنون هیچ کاربری از این پست تشکر نکرده است

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید