کلاس ها

ES6 مفهوم "کلاس" را در جاوا اسکریپت معرفی کرد که با کلاس های دیگر زبان های برنامه نویسی متفاوت است. در اینجا، کلاس‌ها توابع خاصی هستند که به عنوان الگوهایی برای ایجاد اشیایی که قبلاً حاوی داده‌ها، ویژگی‌های مرتبط با آن داده‌ها و روش‌های مربوط به دستکاری آن داده‌ها هستند، عمل می‌کنند. این اشیا، خصوصیات و متدها در مجموع «عضو» کلاس نامیده می شوند.

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

class MyClass {}

کلاس ها برای ارائه راه های در دسترس تر برای کار با ویژگی های پیشرفته نمونه های اولیه و توابع سازنده در نظر گرفته شده اند:

class MyClass {}

typeof MyClass;
> "function"

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

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

class MyClass {}

const myClassInstance = new MyClass();

myClassInstance;
> Object { }

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

class MyClass {
    classMethod() {
        console.log( "My class method." );
    }
}

const myClassInstance = new MyClass();

myClassInstance.classMethod();
> "My class method."

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

class MyClass {
  classMethod() {
    console.log( "My class method." );
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance;
> Object { }
    <prototype>: Object { … }
        classMethod: function classMethod()
        constructor: class MyClass { constructor(myPassedValue) }
        <prototype>: Object { … }

myClassInstance.classMethod();
> "My class method."

ایجاد یک نمونه از یک کلاس، متد constructor() ویژه ای را فراخوانی می کند که هر "تنظیم" لازم را برای نمونه تازه ایجاد شده انجام می دهد و هر ویژگی مرتبط با آن را مقداردهی اولیه می کند. هر آرگومان ارسال شده به کلاس هنگام ایجاد نمونه برای متد constructor() در دسترس است:

class MyClass {
  constructor( myPassedValue ) {
    console.log( myPassedValue );
  }
}

const myClassInstance = new MyClass( "A string." );
> "A string."

در داخل بدنه یک کلاس، مقدار this به خود نمونه اشاره می‌کند، با هر ویژگی که در this تعریف شده است، به عنوان ویژگی‌های هر نمونه از آن کلاس نمایش داده می‌شود:

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProperty = myPassedValue;
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance;
> Object { instanceProperty: "A string." }

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

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProp = myPassedValue;
  }
  myMethod() {
    console.log( this.instanceProp );
  }
}

const myClassInstance = new MyClass( "A string." );

myClassInstance.myMethod();
> "A string."

اگر یک constructor() برای کلاس خود تعریف نکنید، موتور جاوا اسکریپت یک constructor "پیش فرض" خالی فرض می کند. هر کلاس فقط می تواند یک متد خاص به نام constructor() داشته باشد:

class MyClass {
  constructor() {}
  constructor() {}
}
> Uncaught SyntaxError: A class may only have one constructor

شما می توانید یک کلاس را با استفاده از اعلان کلاس یا عبارت کلاس تعریف کنید. نمونه‌های قبلی همگی اعلان‌های کلاس بوده‌اند که نیاز به فراخوانی نام‌ها با استفاده از new دارند. عبارات کلاس را می توان نامگذاری کرد یا بدون نام رها کرد تا یک کلاس "ناشناس" ایجاد شود.

let ClassExpression = class {
    constructor() {}
};

ClassExpression;
> class  {}

یکی از مواردی که می توانید از عبارات کلاس ناشناس برای آن استفاده کنید، توابعی است که کلاس ها را "در حال پرواز" می سازند:

function classMaker() {
  return class {
    constructor() {}
  };
}

let MyVariable = classMaker();

MyVariable;
> class  {}

اعلام مجدد یک کلاس با استفاده از اعلان کلاس باعث ایجاد یک خطای نحوی می شود:


class MyClass {
    constructor( ) {
        console.log( "My class." );
    }
};

class MyClass {
    constructor() {
        console.log( "My new class." );
    }
};
> Uncaught SyntaxError: redeclaration of class MyClass

با این حال، عبارات کلاس به شما امکان می دهد یک کلاس را دوباره تعریف کنید:

let ClassExpression = class MyClass { };

ClassExpression = class MyOtherClass {
    constructor( myString ) {
        this.myProp = myString;
    }
};

new ClassExpression( "String." );
> MyOtherClass {myProp: 'String.'}

شما نمی توانید یک عبارت کلاس نامگذاری شده را با نام فراخوانی کنید، همانطور که می توانید یک اعلان کلاس را انجام دهید. با این حال، نام اختصاص داده شده یک عبارت کلاس به عنوان ویژگی نمونه ایجاد شده، بیشتر برای آسان کردن اشکال زدایی در دسترس است:

let MyVariable = class MyClass {};

MyClass;
> Uncaught ReferenceError: MyClass is not defined

MyVariable;
> class MyClass {}

MyVariable.name;
> "MyClass"

هنگامی که یک متغیر را با استفاده از یک عبارت کلاس مقداردهی اولیه می کنید، قوانین hoisting آن متغیر همانطور که انتظار می رود رعایت می شود. اعلان‌های کلاس از همان قوانین "منطقه مرده زمانی" مانند let و const پیروی می‌کنند و به گونه‌ای رفتار می‌کنند که گویی در بالای محدوده فعلی خود بالا نیامده‌اند، به این معنی که فراخوانی یک کلاس قبل از اعلان کلاس باعث خطا می‌شود:

{
    let myVar = new MyClass( "Property string." );

    class MyClass {
        myProp;

        constructor( myString ) {
            this.myProp = myString;
        }
    };
};
> Uncaught ReferenceError: Cannot access 'MyClass' before initialization

درک خود را بررسی کنید

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

class MyClass {}
myClass = class {}
new class()

یک کلاس چند متد constructor() می تواند داشته باشد؟

یکی
هیچ یک
نامحدود