Lớp

ES6 đã giới thiệu khái niệm "lớp học" trong JavaScript, khác với bằng các ngôn ngữ lập trình khác. Ở đây, lớp là các hàm đặc biệt đóng vai trò là mẫu để tạo các đối tượng đã chứa dữ liệu, thuộc tính có liên quan đến dữ liệu đó và các phương thức liên quan đến việc thao túng dữ liệu đó. Các đối tượng, thuộc tính và phương thức này được gọi chung là "thành phần" của .

Để xác định một lớp, hãy sử dụng từ khoá class. Làm theo phương pháp hay nhất và quy ước được thiết lập bởi các hàm hàm khởi tạo tích hợp trong JavaScript, hãy bắt đầu bất kỳ giá trị nhận dạng của một lớp có chữ cái viết hoa:

class MyClass {}

Đây là lớp học nhằm cung cấp các phương pháp dễ tiếp cận hơn để làm việc với các tính năng của nguyên mẫu và hàm khởi tạo:

class MyClass {}

typeof MyClass;
> "function"

Do các lớp được thêm vào một phần để hỗ trợ JavaScript nâng cao tính năng dễ sử dụng và hấp dẫn hơn, đôi khi còn được gọi là "cú pháp dễ hiểu". Tuy nhiên, không chỉ cung cấp cách viết tắt hữu ích để làm việc với tính kế thừa nguyên mẫu. Giới thiệu cú pháp lớp, tạo cơ hội để giải quyết các vấn đề thiết kế lâu dài trong JavaScript mà không gây ra vấn đề về khả năng tương thích ngược. Như một ví dụ: tất cả mã bên trong phần nội dung của một lớp luôn được đánh giá trong chế độ nghiêm ngặt.

Để tạo một thực thể của một lớp, hãy sử dụng toán tử new.

class MyClass {}

const myClassInstance = new MyClass();

myClassInstance
;
> Object { }

Các hàm được xác định bên trong phần nội dung của một lớp được biểu thị dưới dạng phương thức của mỗi lớp thực thể của lớp đó.

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

const myClassInstance = new MyClass();

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

Phương thức được xác định trong một lớp sẽ trở thành phương thức trên nguyên mẫu của thực thể thu được. Do bản chất của chuỗi nguyên mẫu, bạn có thể gọi các phương thức này trực tiếp trên đối tượng thu được:

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

Việc tạo một thực thể của một lớp sẽ gọi một phương thức constructor() đặc biệt thực hiện mọi hoạt động "thiết lập" cần thiết cho thực thể mới tạo và khởi chạy bất kỳ thuộc tính nào được liên kết với thuộc tính đó. Bất kỳ đối số nào được truyền đến lớp khi thực thể được tạo có sẵn cho phương thức constructor():

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

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

Trong phần nội dung của một lớp, giá trị của this tham chiếu đến chính thực thể đó, với bất kỳ thuộc tính nào được xác định trên this được hiển thị dưới dạng thuộc tính của mỗi thực thể của lớp đó:

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

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

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

Các thuộc tính này cũng áp dụng cho mọi phương thức trong phần nội dung của lớp:

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

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

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

Nếu bạn không xác định constructor() cho lớp của mình, công cụ JavaScript giả định giá trị "mặc định" trống constructor Mỗi lớp chỉ có thể có một đặc biệt phương thức có tên constructor():

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

Bạn có thể xác định một lớp bằng cách sử dụng khai báo lớp hoặc biểu thức lớp. Các ví dụ trước đều là khai báo lớp, Quy tắc này yêu cầu gọi tên bằng new. Biểu thức lớp có thể được đặt tên hoặc để trống tên để tạo một "ẩn danh" .

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

ClassExpression;
> class  {}

Bạn có thể sử dụng biểu thức lớp ẩn danh cho các hàm tạo lớp học "khi di chuyển:"

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

let
MyVariable = classMaker();

MyVariable;
> class  {}

Việc khai báo lại một lớp bằng phần khai báo lớp sẽ gây ra lỗi cú pháp:


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

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

Tuy nhiên, biểu thức lớp cho phép bạn xác định lại một lớp:

let ClassExpression = class MyClass { };

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

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

Bạn không thể gọi một biểu thức lớp có tên theo tên theo cách mà bạn có thể dùng một lớp khai báo. Tuy nhiên, tên được chỉ định của biểu thức lớp có sẵn dưới dạng của phiên bản đã tạo, chủ yếu là để gỡ lỗi dễ dàng hơn:

let MyVariable = class MyClass {};

MyClass;
> Uncaught ReferenceError: MyClass is not defined

MyVariable;
> class MyClass {}

MyVariable.name;
> "MyClass"

Khi bạn khởi tạo một biến bằng biểu thức lớp, quy tắc di chuyển lên trên biến đó được tuân theo như dự kiến. Nội dung khai báo về lớp tuân theo cùng một "vùng chết tạm thời" các quy tắc với letconst, và hoạt động như thể chúng chưa được chuyển lên đầu phạm vi hiện tại, tức là việc gọi một lớp trước khi khai báo lớp sẽ gây ra lỗi:

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

   
class MyClass {
        myProp
;

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

Kiểm tra kiến thức

Câu nào sau đây xác định đúng một lớp?

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

Một lớp có thể có bao nhiêu phương thức constructor()?

Vé loại không giới hạn
Không có
Một