فصل نوزدهم: کار با کلاس در اکما اسکریپت

31 شهریور 1397
es6-classes

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

شی گرایی، یک برنامه را مجموعه ای از اشیاء که با مکانیزمی به نام متد با هم ارتباط برقرار می کنند تعریف می کند. ES6 از این مولفه های شی گرایی هم پشتیبانی می کند.

مفهوم برنامه شی گرایی

برای شروع کار باید با مفاهیم زیر آشنا شوید.

شی: یک شی، وضعیت یک موجودیت را در هر لحظه نمایش می دهد. طبق گفته Grady Brooch هر شی سه ویژگی دارد:

  • وضعیت(State): توسط خصیصه های یک شی توصیف می شود.
  • رفتار(Behavior): طرز کار یک شی را توصیف می کند.
  • شناسایی(identify): یک مقدار منحصر به فرد که یک شی را از مجموعه ای از اشیای یکسان متمایز می کند.

کلاس: یک چهارچوب برای ایجاد اشیاء است. کلاس، داده ها را برای شی کپسوله می کند.

متد: متدها ارتباط بین اشیا را تسهیل می کند.

حال بیایید این مفاهیم شی گرایی را در دنیای واقعی بررسی کنیم. برای مثال، ماشین یک شی است که شامل یک سری داده ها (سال ساخت، مدل، تعداد درب ها، شماره وسیله نقلیه و...) و قابلیت ها (شتاب، جهش، باز شدن درب ها، روشن کردن چراغ ها، و... ) است.

در ES6 کلاس ها با کلمه کلیدی class ساخته می شود. کلاس ها به دو روش ساخته می شوند؛ روش اول، اعلان یک کلاس و روش دوم استفاده از کلمه کلیدی new.

سینتکس اعلان یک کلاس

class Class_name {  
}

سینتکس تعریف کلاس

var var_name = new Class_name {  
}

مثال اول، کلمه کلیدی class به همراه نام کلاس آمده است. قوانینی که برای نامگذاری شناسه ها حاکم است، در مورد کلاس ها هم به همان صورت استفاده می شود.

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

  • سازنده ها: سازنده ها وظیفه تخصیص حافظه برای اشیاء را بر عهده دارند.
  • توابع: توابع کارهایی را که یک شی می تواند انجام دهد، مشخص می کند. به توابع، متد هم گفته می شود.

مجموع این دو مولفه، اعضای داده ای یک کلاس را تشکیل می دهند.

نکته: بدنه یک کلاس فقط می تواند شامل توابع باشد، نه داده ها.

مثال: اعلان یک کلاس

class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

مثال: تعریف یک کلاس

var Polygon = class { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

کدهای بالا یک دستور کلاس بدون نام را نشان می دهند. در مثال زیر یک نام برای کلاس مشخص کردیم.

var Polygon = class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

نکته: بر خلاف متغیر و توابع، کلاس ها نمی توانند hoist شوند.

ایجاد اشیاء

برای ایجاد یک نمونه از کلاس باید از کلمه کلیدی new به همراه نام کلاس استفاده کنید.

var object_name= new class_name([ arguments ])

کلمه کلیدی new مسئول نمونه گیری از کلاس است. سمت راست عبارت، سازنده را فراخوانی کرده است. در صورتی که هنگام تعریف سازنده برای آن پارامتر تعریف شده باشد، باید پارامتر آن را هم در اینجا مشخص کنید.

مثال: نمونه گیری از یک کلاس

var obj = new Polygon(10,12)

دسترسی به توابع

از طریق یک شی می توان به خصیصه و توابع یک کلاس دسترسی داشت. با استفاده از علامت نقطه (.) میتوان به اعضای داده یک کلاس دسترسی داشت.

//accessing a function 
obj.function_name()

مثال کامل

'use strict' 
class Polygon { 
   constructor(height, width) { 
      this.h = height; 
      this.w = width;
   } 
   test() { 
      console.log("The height of the polygon: ", this.h) 
      console.log("The width of the polygon: ",this. w) 
   } 
} 

//creating an instance  
var polyObj = new Polygon(10,20); 
polyObj.test();

در مثال بالا یک کلاس به نام polygon تعریف شده است. سازنده کلاس دو آرگومان به نام های height و wight می گیرد و کلمه کلیدی this به نمونه جاری کلاس اشاره می کند. به عبارت دیگر سازنده بالا با مقادیری که به عنوان پارامتر به آن پاس داده شد، متغیرهای h و w را مقداردهی می کند.

تابع test() مقادیر hight و  wight را چاپ می کند. برای استفاده از این اسکریپت، یک نمونه از کلاس ایجاد می کنیم. نمونه ایجاد شده را به متغیرهای polyObj نسبت می دهیم.

خروجی

The height of the polygon:  10 
The width of the polygon:  20

کلمه کلیدی static

کلمه کلیدی static به توابع یک کلاس اعمال می شوند.اعضای static توسط نام کلاس ارجاع داده می شوند.

مثال:

'use strict' 
class StaticMem { 
   static disp() { 
      console.log("Static Function called") 
   } 
} 
StaticMem.disp() //invoke the static metho

نکته: تعریف متد سازنده کاملاً اختیاری است. هر کلاس به طور پیش فرض یک متد سازنده دارد.

خروجی کد بالا

Static Function called

عملگر instanceof

عملگر instanceof نوع یک شی را بررسی می کند و یک نوع بولین را بسته به نتیجه مقایسه بر می گرداند.

مثال

'use strict' 
class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson);

خروجی

obj is an instance of Person True

ارث بری کلاس

ES6 از مفهومی به نام وراثت پشتیبانی می کند. وراثت توانایی ایجاد یک نمونه جدید از نمونه موجود در یک کلاس است. کلاسی که از آن ارث بری شده، کلاس والد یا super می گویند و کلاس جدید ساخته شده، کلاس فرزند یا زیرکلاس می نامند. یک کلاس می تواند توسط کلمه کلیدی extends از کلاس دیگر ارث برای کند. کلاس فرزند تمام پروپرتی ها و متدهای کلاس والد بجز متد سازنده را ارث بری می کند.

سینتکس آن عبارت است از :

class child_class_name extends parent_class_name

مثال: ارث بری کلاس

'use strict' 
class Shape { 
   constructor(a) { 
      this.Area = a
   } 
} 
class Circle extends Shape { 
   disp() { 
      console.log("Area of the circle:  "+this.Area) 
   } 
} 
var obj = new Circle(223); 
obj.disp()

در مثال بالا یک کلاس به نام shape تعریف کردیم. سپس کلاس circle از آن کلاس ارث بری کرده است. چون بین این کلاس ها رابطه وراثت وجود دارد، کلاس circle به طور ضمنی به پروپرتی های کلاس والد مثل area دسترسی دارد.

خروجی کد بالا

Area of Circle: 223

وراثت به دسته های زیر تقسیم می شوند:

  • یگانه: یک کلاس تنها از یک کلاس دیگر ارث بری می کند، یعنی فقط یک کلاس والد دارد.
  • چندگانه: یک کلاس می تواند از چندین کلاس ارث بری کند.اکمااسکریپت 6 از وراثت چندگانه پشتیبانی نمی کند.
  • چند سطحی: در مثال زیر نشان داده شده است. 
'use strict' 
class Root { 
   test() { 
      console.log("call from parent class") 
   } 
} 
class Child extends Root {} 
class Leaf extends Child   

//indirectly inherits from Root by virtue of inheritance {} 
var obj = new Leaf();
obj.test()

کلاسLeaf به پروپرتی های کلاس های Root و child از طریق وراثت چند سطحی دسترسی دارد.

خروجی

 call from parent class

ارث بری کلاس و override کردن متدها

Override کردن متدها مکانیزمی است که در آن کلاس فرزند متدهای کلاس والد را دوباره تعریف می کند.

مثال زیر نحوه انجام اینکار را نشان داده است.

'use strict' ;
class PrinterClass { 
   doPrint() { 
      console.log("doPrint() from Parent called… ");
   }
}
class StringPrinter extends PrinterClass { 
   doPrint() { 
      console.log("doPrint() is printing a string…"); 
   } 
} 
var obj = new StringPrinter(); 
obj.doPrint();

در مثال بالا، کلاس فرزند پیاده سازی کلاس والد را تغییر داده است.

خروجی

doPrint() is printing a string…

کلاس super

اکما اسکریپت 6 به کلاس فرزند این امکان را می دهد تا اعضای داده ای کلاس والدش را فراخوانی کند.اینکار توسط کلمه کلیدی super انجام میشود. کلمه کلیدی super برای ارجاع به کلاس والد استفاده می شود.

مثال

'use strict' 
class PrinterClass { 
   doPrint() {
      console.log("doPrint() from Parent called…") 
   } 
}  
class StringPrinter extends PrinterClass { 
   doPrint() { 
      super.doPrint() 
      console.log("doPrint() is printing a string…") 
   } 
} 
var obj = new StringPrinter() 
obj.doPrint()

متد doPrint() در کلاس stringPrinter دوباره تعریف شده است، که اینکار با یک فراخوانی به کلاس والد آن انجام شده است.

به عبارت دیگر کلمه کلیدی super برای فراخوانی تعریف تابع doPrint() در کلاس والد (کلاس PrinterClass) استفاده شده است.

خروجی

doPrint() from Parent called. 
doPrint() is printing a string.
نویسنده شوید

دیدگاه‌های شما

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