Trong lập trình hướng đối tượng, một lớp là một mẫu mã chương trình mở rộng để tạo các đối tượng, cung cấp các giá trị ban đầu cho các biến trạng thái [biến thành viên] và triển khai hành vi [hàm thành viên hoặc phương thức].
Trong thực tế, chúng ta thường cần tạo ra nhiều đối tượng cùng loại, như người dùng hoặc hàng hóa hoặc bất cứ thứ gì.
Như chúng ta đã biết từ Trình xây dựng chương, nhà điều hành "mới",
class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
8 có thể giúp với điều đó.Nhưng trong JavaScript hiện đại, có một cấu trúc lớp học nâng cao hơn, giới thiệu các tính năng mới tuyệt vời hữu ích cho lập trình hướng đối tượng.
Cú pháp của lớp ”
Cú pháp cơ bản là:
class MyClass {
// class methods
constructor[] { ... }
method1[] { ... }
method2[] { ... }
method3[] { ... }
...
}
Sau đó sử dụng
class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
9 để tạo một đối tượng mới với tất cả các phương thức được liệt kê.Phương thức
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
0 được gọi tự động bởi class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
1, vì vậy chúng ta có thể khởi tạo đối tượng ở đó.Ví dụ:
class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
Khi
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
2 được gọi:- Một đối tượng mới được tạo ra.
3 chạy với đối số đã cho và gán nó choclass User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // proof: User is a function alert[typeof User]; // function
4.class User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // proof: User is a function alert[typeof User]; // function
Sau đó, chúng ta có thể gọi các phương thức đối tượng, chẳng hạn như
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
5.
Không có dấu phẩy giữa các phương pháp lớp
Một cạm bẫy phổ biến cho các nhà phát triển người mới là đặt dấu phẩy giữa các phương pháp lớp, điều này sẽ dẫn đến lỗi cú pháp.
Ký hiệu ở đây là không bị nhầm lẫn với các chữ cái đối tượng. Trong lớp, không cần dấu phẩy.
Lớp học là gì?
Vì vậy, chính xác thì
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
6 là gì? Đó không phải là một thực thể cấp ngôn ngữ hoàn toàn mới, như người ta có thể nghĩ.Hãy để tiết lộ bất kỳ phép thuật nào và xem một lớp học thực sự là gì. Điều đó sẽ giúp tìm hiểu nhiều khía cạnh phức tạp.
Trong JavaScript, một lớp là một loại chức năng.
Ở đây, hãy xem:
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
Những gì
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
7 Cấu trúc thực sự làm là:- Tạo một hàm có tên
8, điều đó trở thành kết quả của khai báo lớp. Mã chức năng được lấy từ phương thứcclass User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // proof: User is a function alert[typeof User]; // function
3 [giả sử trống nếu chúng ta không viết phương thức đó].class User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // proof: User is a function alert[typeof User]; // function
- Lưu trữ các phương thức lớp, chẳng hạn như
0, trongclass User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // class is a function alert[typeof User]; // function // ...or, more precisely, the constructor method alert[User === User.prototype.constructor]; // true // The methods are in User.prototype, e.g: alert[User.prototype.sayHi]; // the code of the sayHi method // there are exactly two methods in the prototype alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
1.class User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // class is a function alert[typeof User]; // function // ...or, more precisely, the constructor method alert[User === User.prototype.constructor]; // true // The methods are in User.prototype, e.g: alert[User.prototype.sayHi]; // the code of the sayHi method // there are exactly two methods in the prototype alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
Sau khi đối tượng
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// class is a function
alert[typeof User]; // function
// ...or, more precisely, the constructor method
alert[User === User.prototype.constructor]; // true
// The methods are in User.prototype, e.g:
alert[User.prototype.sayHi]; // the code of the sayHi method
// there are exactly two methods in the prototype
alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
2 được tạo, khi chúng ta gọi phương thức của nó, nó được lấy từ nguyên mẫu, giống như được mô tả trong chương F.Prototype. Vì vậy, đối tượng có quyền truy cập vào các phương thức lớp.Chúng ta có thể minh họa kết quả của tuyên bố
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// class is a function
alert[typeof User]; // function
// ...or, more precisely, the constructor method
alert[User === User.prototype.constructor]; // true
// The methods are in User.prototype, e.g:
alert[User.prototype.sayHi]; // the code of the sayHi method
// there are exactly two methods in the prototype
alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
3 như:
Đây là mã để hướng nội:
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// class is a function
alert[typeof User]; // function
// ...or, more precisely, the constructor method
alert[User === User.prototype.constructor]; // true
// The methods are in User.prototype, e.g:
alert[User.prototype.sayHi]; // the code of the sayHi method
// there are exactly two methods in the prototype
alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
Không chỉ là một đường cú pháp
Đôi khi, mọi người nói rằng
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
6 là một đường cú pháp của người Hồi giáo [cú pháp được thiết kế để làm cho mọi thứ dễ đọc hơn, nhưng không giới thiệu bất cứ điều gì mới], bởi vì chúng tôi thực sự có thể khai báo điều tương tự mà không cần sử dụng từ khóa class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
6: tất cả:// rewriting class User in pure functions
// 1. Create constructor function
function User[name] {
this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it
// 2. Add the method to prototype
User.prototype.sayHi = function[] {
alert[this.name];
};
// Usage:
let user = new User["John"];
user.sayHi[];
Kết quả của định nghĩa này là về cùng. Vì vậy, thực sự có những lý do tại sao
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
6 có thể được coi là một đường cú pháp để xác định một hàm tạo cùng với các phương pháp nguyên mẫu của nó.Tuy nhiên, có những khác biệt quan trọng.
Đầu tiên, một hàm được tạo bởi
6 được dán nhãn bởi một thuộc tính nội bộ đặc biệtclass User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // proof: User is a function alert[typeof User]; // function
8. Vì vậy, nó không hoàn toàn giống như tạo ra nó bằng tay.class User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // class is a function alert[typeof User]; // function // ...or, more precisely, the constructor method alert[User === User.prototype.constructor]; // true // The methods are in User.prototype, e.g: alert[User.prototype.sayHi]; // the code of the sayHi method // there are exactly two methods in the prototype alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
Ngôn ngữ kiểm tra tài sản đó ở nhiều nơi. Ví dụ: không giống như một chức năng thông thường, nó phải được gọi bằng
1:class User { constructor[name] { this.name = name; } sayHi[] { alert[this.name]; } } // proof: User is a function alert[typeof User]; // function
class User { constructor[] {} } alert[typeof User]; // function User[]; // Error: Class constructor User cannot be invoked without 'new'
Ngoài ra, một biểu diễn chuỗi của một hàm tạo lớp trong hầu hết các công cụ JavaScript bắt đầu với lớp lớp
class User { constructor[] {} } alert[User]; // class User { ... }
Có những khác biệt khác, chúng tôi sẽ gặp họ sớm.
Phương pháp lớp là không thể kích động. Một định nghĩa lớp đặt cờ
0 thành// rewriting class User in pure functions // 1. Create constructor function function User[name] { this.name = name; } // a function prototype has "constructor" property by default, // so we don't need to create it // 2. Add the method to prototype User.prototype.sayHi = function[] { alert[this.name]; }; // Usage: let user = new User["John"]; user.sayHi[];
1 cho tất cả các phương thức trong// rewriting class User in pure functions // 1. Create constructor function function User[name] { this.name = name; } // a function prototype has "constructor" property by default, // so we don't need to create it // 2. Add the method to prototype User.prototype.sayHi = function[] { alert[this.name]; }; // Usage: let user = new User["John"]; user.sayHi[];
2.// rewriting class User in pure functions // 1. Create constructor function function User[name] { this.name = name; } // a function prototype has "constructor" property by default, // so we don't need to create it // 2. Add the method to prototype User.prototype.sayHi = function[] { alert[this.name]; }; // Usage: let user = new User["John"]; user.sayHi[];
Điều đó tốt, bởi vì nếu chúng ta
3 trên một đối tượng, chúng ta thường không muốn các phương pháp lớp của nó.// rewriting class User in pure functions // 1. Create constructor function function User[name] { this.name = name; } // a function prototype has "constructor" property by default, // so we don't need to create it // 2. Add the method to prototype User.prototype.sayHi = function[] { alert[this.name]; }; // Usage: let user = new User["John"]; user.sayHi[];
Các lớp luôn luôn
4. Tất cả mã bên trong cấu trúc lớp tự động ở chế độ nghiêm ngặt.// rewriting class User in pure functions // 1. Create constructor function function User[name] { this.name = name; } // a function prototype has "constructor" property by default, // so we don't need to create it // 2. Add the method to prototype User.prototype.sayHi = function[] { alert[this.name]; }; // Usage: let user = new User["John"]; user.sayHi[];
Bên cạnh đó, cú pháp
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
6 mang đến nhiều tính năng khác mà chúng tôi sẽ khám phá sau.Biểu thức lớp
Giống như các chức năng, các lớp có thể được xác định bên trong một biểu thức khác, được truyền xung quanh, trả về, được chỉ định, v.v.
Ở đây, một ví dụ về biểu thức lớp:
let User = class {
sayHi[] {
alert["Hello"];
}
};
Tương tự như các biểu thức chức năng được đặt tên, các biểu thức lớp có thể có tên.
Nếu một biểu thức lớp có tên, nó chỉ hiển thị bên trong lớp:
// "Named Class Expression"
// [no such term in the spec, but that's similar to Named Function Expression]
let User = class MyClass {
sayHi[] {
alert[MyClass]; // MyClass name is visible only inside the class
}
};
new User[].sayHi[]; // works, shows MyClass definition
alert[MyClass]; // error, MyClass name isn't visible outside of the class
Chúng ta thậm chí có thể làm cho các lớp động tự động theo yêu cầu, như thế này:
function makeClass[phrase] {
// declare a class and return it
return class {
sayHi[] {
alert[phrase];
}
};
}
// Create a new class
let User = makeClass["Hello"];
new User[].sayHi[]; // Hello
Getters/setters
Giống như các đối tượng theo nghĩa đen, các lớp có thể bao gồm getters/setters, thuộc tính được tính toán, v.v.
Ở đây, một ví dụ cho
// rewriting class User in pure functions
// 1. Create constructor function
function User[name] {
this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it
// 2. Add the method to prototype
User.prototype.sayHi = function[] {
alert[this.name];
};
// Usage:
let user = new User["John"];
user.sayHi[];
6 được triển khai bằng cách sử dụng // rewriting class User in pure functions
// 1. Create constructor function
function User[name] {
this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it
// 2. Add the method to prototype
User.prototype.sayHi = function[] {
alert[this.name];
};
// Usage:
let user = new User["John"];
user.sayHi[];
7:class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
0Về mặt kỹ thuật, khai báo lớp như vậy hoạt động bằng cách tạo getters và setters trong
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// class is a function
alert[typeof User]; // function
// ...or, more precisely, the constructor method
alert[User === User.prototype.constructor]; // true
// The methods are in User.prototype, e.g:
alert[User.prototype.sayHi]; // the code of the sayHi method
// there are exactly two methods in the prototype
alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
1.Tên được tính toán […]
Ở đây, một ví dụ với tên phương thức được tính toán bằng dấu ngoặc
// rewriting class User in pure functions
// 1. Create constructor function
function User[name] {
this.name = name;
}
// a function prototype has "constructor" property by default,
// so we don't need to create it
// 2. Add the method to prototype
User.prototype.sayHi = function[] {
alert[this.name];
};
// Usage:
let user = new User["John"];
user.sayHi[];
9:class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
1Các tính năng như vậy rất dễ nhớ, vì chúng giống với các đối tượng theo nghĩa đen.
Trường lớp
Các trình duyệt cũ có thể cần một polyfill
Các trường lớp là một bổ sung gần đây cho ngôn ngữ.
Trước đây, các lớp của chúng tôi chỉ có phương pháp.
Các trường lớp học trực tuyến là một cú pháp cho phép thêm bất kỳ thuộc tính nào.
Chẳng hạn, hãy để thêm thuộc tính
class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
0 vào class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// class is a function
alert[typeof User]; // function
// ...or, more precisely, the constructor method
alert[User === User.prototype.constructor]; // true
// The methods are in User.prototype, e.g:
alert[User.prototype.sayHi]; // the code of the sayHi method
// there are exactly two methods in the prototype
alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
3:class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
2Vì vậy, chúng tôi chỉ viết "=" trong tuyên bố, và đó là nó.
Sự khác biệt quan trọng của các trường lớp là chúng được đặt trên các đối tượng riêng lẻ chứ không phải
class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// class is a function
alert[typeof User]; // function
// ...or, more precisely, the constructor method
alert[User === User.prototype.constructor]; // true
// The methods are in User.prototype, e.g:
alert[User.prototype.sayHi]; // the code of the sayHi method
// there are exactly two methods in the prototype
alert[Object.getOwnPropertyNames[User.prototype]]; // constructor, sayHi
1:class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
3
Chúng ta cũng có thể gán các giá trị bằng cách sử dụng các biểu thức và các lệnh gọi chức năng phức tạp hơn:
class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
4Tạo các phương thức ràng buộc với các trường lớp
Như đã được chứng minh trong chức năng chức năng liên kết chức năng trong JavaScript có
class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
3 động. Nó phụ thuộc vào bối cảnh của cuộc gọi.Vì vậy, nếu một phương thức đối tượng được truyền xung quanh và được gọi trong một bối cảnh khác,
class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
3 won sẽ là một tham chiếu đến đối tượng của nó nữa.Chẳng hạn, mã này sẽ hiển thị
class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
5:class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
5Vấn đề được gọi là "Mất
class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
3".Có hai cách tiếp cận để sửa nó, như đã thảo luận trong chức năng liên kết chức năng chương:
- Vượt qua chức năng bao bọc, chẳng hạn như
7.class User { constructor[] {} } alert[typeof User]; // function User[]; // Error: Class constructor User cannot be invoked without 'new'
- Liên kết phương thức với đối tượng, ví dụ: trong hàm tạo.
Các trường lớp cung cấp một cú pháp khác, khá thanh lịch:
class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
6Trường lớp
class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
8 được tạo trên cơ sở trên mỗi đối tượng, có một hàm riêng cho mỗi đối tượng class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
9, với class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
3 bên trong nó tham chiếu đối tượng đó. Chúng ta có thể vượt qua class User {
constructor[] {}
}
alert[User]; // class User { ... }
1 xung quanh bất cứ nơi nào và giá trị của class User {
constructor[] {}
}
alert[typeof User]; // function
User[]; // Error: Class constructor User cannot be invoked without 'new'
3 sẽ luôn đúng.Điều đó đặc biệt hữu ích trong môi trường trình duyệt, cho người nghe sự kiện.
Bản tóm tắt
Cú pháp lớp cơ bản trông như thế này:
class User {
constructor[name] {
this.name = name;
}
sayHi[] {
alert[this.name];
}
}
// Usage:
let user = new User["John"];
user.sayHi[];
7class User {
constructor[] {}
}
alert[User]; // class User { ... }
3 về mặt kỹ thuật là một hàm [một hàm mà chúng tôi cung cấp dưới dạng class User {
constructor[name] { this.name = name; }
sayHi[] { alert[this.name]; }
}
// proof: User is a function
alert[typeof User]; // function
3], trong khi các phương thức, getters và setters được viết thành class User {
constructor[] {}
}
alert[User]; // class User { ... }
5.Trong các chương tiếp theo, chúng tôi sẽ tìm hiểu thêm về các lớp học, bao gồm cả kế thừa và các tính năng khác.