فیلدها و روش های کلاس

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

class MyClass {
    myField;
}

const myClassInstance = new MyClass();

myClassInstance;
> MyClass { myField: undefined }

می توانید یک فیلد را با یک مقدار مقداردهی اولیه کنید. این اغلب یک مقدار پیش‌فرض است که منطق درون کلاس می‌تواند آن را بازنویسی کند:

class MyClass {
    myResult = false;
    set setValue( myValue ) {
        this.myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> Object { myResult: false }

myClassInstance.setValue = true;

myClassInstance;\
> Object { myResult: true }

فیلدهای کلاس از نظر عملکردی با ویژگی های متصل به کلاس با استفاده this یکسان هستند. این بدان معنی است که آنها را می توان از خارج از کلاس مانند هر ویژگی دیگری تغییر داد.

class MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

فیلدها مبنایی برای برخی از ویژگی های پیشرفته تر کلاس ها فراهم می کنند.

زمینه ها و روش های خصوصی

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

برای خصوصی کردن یک ویژگی، وقتی شناسه را اعلام می کنید، یک # به ابتدای شناسه اضافه کنید:

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {}
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myPrivateField: true }
    #myPrivateField: true
    <prototype>: Object {  }
        constructor: class MyClass {}
        <prototype>: Object {  }

یک فیلد خصوصی باید در بدنه کلاس حاوی اعلان شود. می توانید مقدار آن را بعداً به عنوان ویژگی this تغییر دهید، اما نمی توانید با استفاده this فیلد را ایجاد کنید.

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

class MyClass {
    #myResult = false;
    set setValue( myValue ) {
        this.#myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myResult: false }

myClassInstance.#myResult = true;
> Uncaught SyntaxError: reference to undeclared private field or method #myResult

myClassInstance.setValue = true;

myClassInstance;\
> MyClass { #myResult: true }

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

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> true

myClassInstance.#myPrivateMethod();
> "This is inside a private method."
class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

myClassInstance.#myPrivateMethod();
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateMethod

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

class MyClass {
    #myPrivateField = true;
}
class ChildClass extends MyClass {
    childMethod() {
        console.log( this.#myPrivateField );
    }
}
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

زمینه ها و روش های استاتیک

فیلدها و متدهای استاتیک اعضای خود کلاس هستند، نه اعضای نمونه های آن کلاس. به همین دلیل، فیلدهای استاتیک یک نقطه مرکزی برای داده‌ها فراهم می‌کنند که برای هر نمونه از یک کلاس منحصر به فرد نخواهد بود، اما ممکن است آن نمونه‌ها نیاز به ارجاع داشته باشند - برای مثال، اطلاعات پیکربندی مشترک. متدهای استاتیک اغلب توابع کاربردی برای کار با نمونه‌های یک کلاس هستند، مانند مقایسه یا مرتب‌سازی نمونه‌ها در برابر فیلدی که در آنها وجود دارد.

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

class MyClass {
    static myStaticField;
    static myStaticMethod() {}
}
const myClassInstance = new MyClass();

همچنین می توانید از نماد نقطه برای ایجاد یک متد استاتیک استفاده کنید:

class MyClass {
    constructor() {}
}
MyClass.myStaticMethod = function() {}

شما نمی توانید از نمونه ای از کلاس آنها به خصوصیات استاتیک دسترسی پیدا کنید، اما آنها در سازنده کلاس در دسترس هستند:

class MyClass {
    static myStaticField = true;
    static myStaticMethod() {
        console.log( "A static method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance.myStaticField;
> undefined

myClassInstance.myStaticMethod();
> Uncaught TypeError: myClassInstance.myStaticMethod is not a function

MyClass.myStaticField;
> true

MyClass.myStaticMethod();
> "A static method."

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

class User {
    constructor( name, email ) {
        this.name = name;
        this.email = email;
    }
    static fromObject( myObject ) {
        return new User( myObject.name, myObject.email ?? "Omitted" );
    }
}
const userObject = {
    "name" : "My Name",
    "email" : "my@email.address"
};
const secondUserObject = {
    "name" : "My Name"
};

const firstUser = User.fromObject( userObject );
const secondUser = User.fromObject( secondUserObject );

firstUser;
> Object { name: "My Name", email: "my@email.address" }

secondUser;
> Object { name: "My Name", email: "Omitted" }

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

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

زمینه های کلاس
زمینه های خصوصی
Static fields