Mở rộng lớp

Từ khoá extends được dùng trong các phần khai báo hoặc biểu thức của lớp để tạo một lớp đóng vai trò là lớp con của một lớp khác, trong đó lớp mẹ (đôi khi được gọi là "lớp cơ sở") đóng vai trò là nguyên mẫu của lớp con (đôi khi gọi là "lớp phụ" hoặc "lớp dẫn xuất").

class ParentClass {}
class ChildClass extends ParentClass {}

Object.getPrototypeOf( ChildClass );
> class ParentClass {}

Các lớp con này kế thừa các thuộc tính và phương thức của lớp mẹ. Điều này cho phép bạn mở rộng chức năng cốt lõi của một lớp để phục vụ nhiều mục đích cụ thể hơn mà không cần làm quá tải lớp mẹ để phù hợp với mọi trường hợp sử dụng có thể, hoặc triển khai lại mã phục vụ mục đích tương tự.

Các lớp con có thể cung cấp cách triển khai riêng cho các phương thức được kế thừa từ lớp mẹ:

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProp = myPassedValue;
  }
  classMethod() {
    console.log( `The value was '${ this.instanceProp }.'`)
  }
}
class ChildClass extends MyClass {
  classMethod() {
    console.log( `The value was '${ this.instanceProp },' and its type was '${ typeof this.instanceProp }.'`)
  }
}

const myParentClassInstance = new MyClass( "My string." );
const mySubclassInstance = new ChildClass( 100 );

myParentClassInstance.classMethod();
> "The value type was 'string.'"

mySubclassInstance.classMethod();
> "The value was '100,' and its type was 'number.'"

Bạn cũng có thể gọi các phương thức được xác định trên lớp mẹ trong bối cảnh của lớp con bằng cách sử dụng super:

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProp = myPassedValue;
  }
  classMethod() {
    console.log( `The value was '${ this.instanceProp }.'`)
  }
}

class ChildClass extends MyClass {
  subclassMethod() {
    super.classMethod();
    console.log( `The value type was '${ typeof this.instanceProp }.'`)
  }
}
const mySubclassInstance = new ChildClass( 100 );

mySubclassInstance.subclassMethod();
> The value was '100.'
> The value type was 'number.'

Như đã thấy trong các ví dụ trước, khi phương thức constructor() bị bỏ qua trong ngữ cảnh của một lớp con, hàm khởi tạo ngầm ẩn của JavaScript sẽ gọi hàm khởi tạo mẹ cùng với cùng một bộ đối số. Tuy nhiên, nếu có một hàm khởi tạo trong lớp con thì trước tiên, lớp đó phải gọi super() cùng với mọi đối số cần thiết trước khi tham chiếu this.

class MyClass {
  constructor( myPassedValue ) {
    this.instanceProp = myPassedValue;
  }
  classMethod() {
    console.log( `The value was '${ this.instanceProp }.'`)
  }
}

class ChildClass extends MyClass {
    constructor( myPassedValue ) {
        super( myPassedValue );
        this.modifiedProp = myPassedValue + 50;
    }\
    subclassMethod() {
        super.classMethod();
        console.log( `The value type was '${ typeof this.instanceProp }.'`)
    }
}
const mySubclassInstance = new ChildClass( 100 );

mySubclassInstance;
> MyClass { instanceProp: 100, modifiedProp: 150 }

Phương thức getter và phương thức setter là các phương thức đặc biệt dùng riêng để truy xuất và xác định giá trị tương ứng. Các phương thức được xác định bằng từ khoá getset cho phép bạn tạo các phương thức có thể tương tác như thể chúng là các thuộc tính tĩnh.

class MyClass {
    constructor( originalValue ) {
        this.totalValue = 0;
    }
    set doubleThisValue( newValue ) {
        this.totalValue = newValue * 2;
    }
    get currentValue() {
        console.log( `The current value is: ${ this.totalValue }` );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { totalValue: 0 }

myClassInstance.doubleThisValue = 20;

myClassInstance.currentValue;
> The current value is: 40

Các thuộc tính getset được xác định trên thuộc tính nguyên mẫu của lớp, nên có sẵn cho mọi thực thể của lớp.

Kiểm tra kiến thức

Chọn câu lệnh đúng về các lớp được tạo bằng từ khoá extends.

Lớp này đóng vai trò là lớp con của lớp mà nó mở rộng.
Lớp này kế thừa các thuộc tính và phương thức của lớp mẹ.
Lớp này đóng vai trò là thành phần mẹ của lớp mà nó mở rộng.
It can't overwrite methods from a parent class.