Các trường và phương thức của lớp

Trường

Các trường của lớp được khai báo trực tiếp trong phần nội dung của lớp, không được thêm một cách rõ ràng dưới dạng thuộc tính của giá trị this. Tuy nhiên, kết quả giống nhau: một thuộc tính được xác định trên các thực thể của lớp đó.

class MyClass {
    myField;
}

const myClassInstance = new MyClass();

myClassInstance;
> MyClass { myField: undefined }

Bạn có thể khởi tạo trường có giá trị. Đây thường là một giá trị mặc định mà logic trong lớp có thể ghi đè:

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 }

Các trường của lớp có chức năng giống với các thuộc tính đính kèm vào lớp đó bằng cách sử dụng this. Điều này có nghĩa là bạn có thể truy cập và sửa đổi các thuộc tính này từ bên ngoài như mọi thuộc tính khác.

class MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

Các trường là cơ sở cho một số tính năng nâng cao hơn của lớp.

Các trường và phương thức riêng tư

Không thể truy cập các trường và phương thức Riêng tư bên ngoài lớp. Một thuộc tính riêng tư được liên kết với một thực thể của một lớp, nghĩa là mỗi thực thể đều chứa tập hợp các trường và phương thức riêng tư, như được xác định trên lớp này.

Để chuyển một thuộc tính sang chế độ riêng tư, hãy thêm # vào đầu giá trị nhận dạng khi bạn khai báo thuộc tính đó:

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

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

Bạn phải khai báo trường riêng tư trong phần nội dung của lớp chứa. Sau này, bạn có thể thay đổi giá trị của trường dưới dạng thuộc tính của this, nhưng bạn không thể tạo trường bằng this.

Bạn không thể truy cập các trường riêng tư từ nơi khác trong tập lệnh. Nhờ vậy, các thuộc tính dữ liệu không bị thay đổi bên ngoài các phương thức getter và setter được cung cấp để tương tác với các giá trị trong đó, đồng thời ngăn quyền truy cập trực tiếp vào các phương thức chỉ dùng trong chính lớp đó.

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 }

Tuy nhiên, xin lưu ý rằng bảng điều khiển dành cho nhà phát triển của trình duyệt thường rất cho phép (mặc dù không nhất quán) về việc cho phép truy cập vào các trường riêng tư cho mục đích gỡ lỗi:

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

Các trường riêng tư có phạm vi chặt chẽ trong phần nội dung của lớp chứa các trường đó, tức là ngay cả lớp con cũng không thể truy cập vào các trường riêng tư liên kết với lớp mẹ:

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

Trường và phương thức tĩnh

Các trường và phương thức tĩnh là các thành phần của chính một lớp, không phải là thành phần của các thực thể của lớp đó. Do đó, các trường tĩnh cung cấp một điểm trung tâm cho dữ liệu. Dữ liệu sẽ không phải là duy nhất cho mỗi thực thể của lớp, nhưng các thực thể đó có thể cần tham chiếu, ví dụ: thông tin cấu hình được chia sẻ. Phương thức tĩnh thường là các hàm hiệu dụng để làm việc với các thực thể của một lớp, chẳng hạn như so sánh hoặc sắp xếp các thực thể với một trường trong đó.

Để xác định các trường và phương thức tĩnh trong phần nội dung của lớp, hãy sử dụng từ khoá static:

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

Bạn cũng có thể dùng ký hiệu dấu chấm để tạo một phương thức tĩnh:

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

Bạn không thể truy cập vào các thuộc tính tĩnh từ một thực thể của lớp, nhưng các thuộc tính này có sẵn trên hàm khởi tạo của lớp:

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."

Về mặt kỹ thuật, các tiện ích này không bắt buộc, nhưng tốt nhất bạn nên sử dụng các phương thức tĩnh để tạo các tiện ích hoạt động với các thực thể của một lớp. Ví dụ: phương thức tĩnh dành riêng để sắp xếp các thực thể của một lớp, hoặc phương thức gốc tĩnh chứa mọi chế độ thiết lập cần thiết để tạo một thực thể của một lớp rồi sau đó trả về thực thể của lớp:

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" }

Kiểm tra kiến thức

Chỉ có thể truy cập vào loại trường nào sau đây từ bên trong lớp?

Trường riêng
Trường lớp
Static fields