ฟิลด์และวิธีการของชั้นเรียน

ช่อง

มีการประกาศช่องคลาสโดยตรงภายในเนื้อหาของคลาส ไม่ได้เพิ่มเป็นพร็อพเพอร์ตี้ของค่า 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 ไม่ได้

ไม่สามารถเข้าถึงช่องส่วนตัวจากที่อื่นในสคริปต์ได้ วิธีนี้จะป้องกันไม่ให้มีการเปลี่ยนแปลงพร็อพเพอร์ตี้ข้อมูลภายนอกเมธอด Getter และ Setter ที่มีให้เพื่อโต้ตอบกับค่าที่มีอยู่ รวมถึงป้องกันไม่ให้มีการเข้าถึงโดยตรงไปยังเมธอดที่มีจุดประสงค์เพื่อใช้ภายในคลาสโดยตรงเท่านั้น

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 }

อย่างไรก็ตาม โปรดทราบว่าโดยทั่วไปแล้ว Developer Console ของเบราว์เซอร์จะได้รับอนุญาตมากแม้ว่าจะไม่สอดคล้องเกี่ยวกับการอนุญาตให้เข้าถึงช่องส่วนตัวเพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่องก็ตาม

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