Với việc giới thiệu Lớp trong TypeScript và ES6, hiện đã tồn tại một số tình huống nhất định yêu cầu các tính năng bổ sung để hỗ trợ chú thích hoặc sửa đổi lớp và thành viên lớp. Trình trang trí cung cấp một cách để thêm cả chú thích và cú pháp lập trình meta cho các khai báo và thành viên lớp. Trang trí là một đề xuất giai đoạn 2 cho JavaScript và có sẵn như một tính năng thử nghiệm của TypeScript
LƯU Ý Trang trí là một tính năng thử nghiệm có thể thay đổi trong các bản phát hành trong tương lai
Để bật hỗ trợ thử nghiệm cho trình trang trí, bạn phải bật tùy chọn trình biên dịch
4 trên dòng lệnh hoặc trongts
function sealed[target] {
// do something with 'target' ...
}
5 của bạnts
function sealed[target] {
// do something with 'target' ...
}
Dòng lệnh
shell
tsc --target ES5 --experimentalDecorators
tsconfig. json
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
người trang trí
Trình trang trí là một loại khai báo đặc biệt có thể được đính kèm với khai báo lớp, phương thức, trình truy cập, thuộc tính hoặc tham số. Người trang trí sử dụng biểu mẫu
6, trong đóts
function sealed[target] {
// do something with 'target' ...
}
7 phải đánh giá một hàm sẽ được gọi trong thời gian chạy với thông tin về khai báo được trang tríts
function sealed[target] {
// do something with 'target' ...
}
Ví dụ, với decorator
8, chúng ta có thể viết hàmts
function sealed[target] {
// do something with 'target' ...
}
9 như sauts
function sealed[target] {
// do something with 'target' ...
}
ts
function sealed[target] {
// do something with 'target' ...
}
nhà máy trang trí
Nếu chúng ta muốn tùy chỉnh cách một trình trang trí được áp dụng cho một khai báo, chúng ta có thể viết một nhà máy trang trí. Nhà máy trang trí chỉ đơn giản là một hàm trả về biểu thức sẽ được gọi bởi trình trang trí khi chạy
Chúng ta có thể viết một nhà máy trang trí theo cách sau
ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
Thành phần trang trí
Nhiều trình trang trí có thể được áp dụng cho một khai báo, ví dụ như trên một dòng
0ts
function sealed[target] {
// do something with 'target' ...
}
Trên nhiều dòng
1ts
function sealed[target] {
// do something with 'target' ...
}
Khi nhiều bộ trang trí áp dụng cho một khai báo, việc đánh giá chúng tương tự như thành phần hàm trong toán học. Trong mô hình này, khi lập các hàm f và g, hợp số thu được [f ∘ g][x] tương đương với f[g[x]]
Như vậy, các bước sau đây được thực hiện khi đánh giá nhiều trình trang trí trên một khai báo trong TypeScript
- Các biểu thức cho mỗi trình trang trí được đánh giá từ trên xuống dưới
- Các kết quả sau đó được gọi là các hàm từ dưới lên trên
Nếu chúng ta sử dụng các nhà máy trang trí, chúng ta có thể quan sát thứ tự đánh giá này với ví dụ sau
2ts
function sealed[target] {
// do something with 'target' ...
}
Cái nào sẽ in đầu ra này ra bàn điều khiển
3ts
function sealed[target] {
// do something with 'target' ...
}
Đánh giá trang trí
Có một thứ tự được xác định rõ ràng về cách áp dụng các trình trang trí cho các khai báo khác nhau bên trong một lớp.
- Trình trang trí tham số, theo sau là Phương thức, Trình truy cập hoặc Trình trang trí thuộc tính được áp dụng cho từng thành viên phiên bản
- Trình trang trí tham số, theo sau là Phương thức, Trình truy cập hoặc Trình trang trí thuộc tính được áp dụng cho từng thành viên tĩnh
- Trình trang trí tham số được áp dụng cho hàm tạo
- Class Decorators được áp dụng cho lớp
Trang trí lớp học
Trình trang trí lớp được khai báo ngay trước khi khai báo lớp. Trình trang trí lớp được áp dụng cho hàm tạo của lớp và có thể được sử dụng để quan sát, sửa đổi hoặc thay thế một định nghĩa lớp. Không thể sử dụng trình trang trí lớp trong tệp khai báo hoặc trong bất kỳ ngữ cảnh xung quanh nào khác [chẳng hạn như trên lớp
0]ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
Biểu thức cho trình trang trí lớp sẽ được gọi là một hàm trong thời gian chạy, với hàm tạo của lớp được trang trí làm đối số duy nhất của nó
Nếu trình trang trí lớp trả về một giá trị, nó sẽ thay thế khai báo lớp bằng hàm tạo được cung cấp
LƯU Ý Nếu chọn trả về một hàm tạo mới, bạn phải cẩn thận để duy trì nguyên mẫu ban đầu. Logic áp dụng các trình trang trí trong thời gian chạy sẽ không làm điều này cho bạn
Sau đây là một ví dụ về trang trí lớp [
8] được áp dụng cho lớpts
function sealed[target] {
// do something with 'target' ...
}
2ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
7ts
function sealed[target] {
// do something with 'target' ...
}
Chúng ta có thể định nghĩa trình trang trí
8 bằng cách sử dụng khai báo hàm sauts
function sealed[target] {
// do something with 'target' ...
}
9ts
function sealed[target] {
// do something with 'target' ...
}
Khi
8 được thực thi, nó sẽ niêm phong cả hàm tạo và nguyên mẫu của nó, và do đó sẽ ngăn chặn bất kỳ chức năng nào khác được thêm vào hoặc xóa khỏi lớp này trong thời gian chạy bằng cách truy cậpts
function sealed[target] {
// do something with 'target' ...
}
5 hoặc bằng cách xác định các thuộc tính trên chínhts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
2 [lưu ý rằng các lớp ES2015 thực sự . Trình trang trí này không ngăn các lớp phân lớpts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
2ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
Tiếp theo, chúng ta có một ví dụ về cách ghi đè hàm tạo để đặt giá trị mặc định mới
0
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
phương pháp trang trí
Trình trang trí phương thức được khai báo ngay trước khi khai báo phương thức. Trình trang trí được áp dụng cho Trình mô tả thuộc tính cho phương thức và có thể được sử dụng để quan sát, sửa đổi hoặc thay thế định nghĩa phương thức. Không thể sử dụng trình trang trí phương thức trong tệp khai báo, khi quá tải hoặc trong bất kỳ ngữ cảnh xung quanh nào khác [chẳng hạn như trong lớp
0]ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
Biểu thức cho trình trang trí phương thức sẽ được gọi là một hàm trong thời gian chạy, với ba đối số sau
- Hàm khởi tạo của lớp đối với thành viên tĩnh hoặc nguyên mẫu của lớp đối với thành viên thể hiện
- Tên của thành viên
- Bộ mô tả thuộc tính cho thành viên
LƯU Ý Bộ mô tả thuộc tính sẽ là
9 nếu mục tiêu tập lệnh của bạn nhỏ hơnts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
00ts
function sealed[target] {
// do something with 'target' ...
}
Nếu trình trang trí phương thức trả về một giá trị, nó sẽ được sử dụng làm Mô tả thuộc tính cho phương thức
LƯU Ý Giá trị trả về bị bỏ qua nếu mục tiêu tập lệnh của bạn nhỏ hơn
00ts
function sealed[target] {
// do something with 'target' ...
}
Sau đây là một ví dụ về một trình trang trí phương thức [
02] được áp dụng cho một phương thức trên lớpts
function sealed[target] {
// do something with 'target' ...
}
03ts
function sealed[target] {
// do something with 'target' ...
}
1
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Chúng ta có thể định nghĩa trình trang trí
02 bằng cách sử dụng khai báo hàm sauts
function sealed[target] {
// do something with 'target' ...
}
2
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Trang trí
05 ở đây là một nhà máy trang trí. Khi trình trang tríts
function sealed[target] {
// do something with 'target' ...
}
05 được gọi, nó sẽ sửa đổi thuộc tínhts
function sealed[target] {
// do something with 'target' ...
}
07 của trình mô tả thuộc tínhts
function sealed[target] {
// do something with 'target' ...
}
Phụ kiện trang trí
Một Accessor Decorator được khai báo ngay trước một khai báo accessor. Trình trang trí bộ truy cập được áp dụng cho Bộ mô tả thuộc tính cho bộ truy cập và có thể được sử dụng để quan sát, sửa đổi hoặc thay thế các định nghĩa của bộ truy cập. Không thể sử dụng trình trang trí trình truy cập trong tệp khai báo hoặc trong bất kỳ ngữ cảnh xung quanh nào khác [chẳng hạn như trong lớp
0]ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
LƯU Ý TypeScript không cho phép trang trí cả trình truy cập
09 vàts
function sealed[target] {
// do something with 'target' ...
}
10 cho một thành viên. Thay vào đó, tất cả các trình trang trí cho thành viên phải được áp dụng cho trình truy cập đầu tiên được chỉ định theo thứ tự tài liệu. Điều này là do các bộ trang trí áp dụng cho Bộ mô tả thuộc tính, kết hợp cả bộ truy cậpts
function sealed[target] {
// do something with 'target' ...
}
09 vàts
function sealed[target] {
// do something with 'target' ...
}
10, không phải mỗi khai báo riêng biệtts
function sealed[target] {
// do something with 'target' ...
}
Biểu thức cho trình trang trí trình truy cập sẽ được gọi là một hàm trong thời gian chạy, với ba đối số sau
- Hàm khởi tạo của lớp đối với thành viên tĩnh hoặc nguyên mẫu của lớp đối với thành viên thể hiện
- Tên của thành viên
- Bộ mô tả thuộc tính cho thành viên
LƯU Ý Bộ mô tả thuộc tính sẽ là
9 nếu mục tiêu tập lệnh của bạn nhỏ hơnts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
00ts
function sealed[target] {
// do something with 'target' ...
}
Nếu trình trang trí trình truy cập trả về một giá trị, nó sẽ được sử dụng làm Trình mô tả thuộc tính cho thành viên
LƯU Ý Giá trị trả về bị bỏ qua nếu mục tiêu tập lệnh của bạn nhỏ hơn
00ts
function sealed[target] {
// do something with 'target' ...
}
Sau đây là một ví dụ về một bộ trang trí truy cập [
16] được áp dụng cho một thành viên của lớpts
function sealed[target] {
// do something with 'target' ...
}
17ts
function sealed[target] {
// do something with 'target' ...
}
3
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Chúng ta có thể định nghĩa trình trang trí
16 bằng cách sử dụng khai báo hàm sauts
function sealed[target] {
// do something with 'target' ...
}
4
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
trang trí tài sản
Trình trang trí thuộc tính được khai báo ngay trước khi khai báo thuộc tính. Không thể sử dụng trình trang trí thuộc tính trong tệp khai báo hoặc trong bất kỳ ngữ cảnh xung quanh nào khác [chẳng hạn như trong lớp
0]ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
Biểu thức cho trình trang trí thuộc tính sẽ được gọi là một hàm trong thời gian chạy, với hai đối số sau
- Hàm khởi tạo của lớp đối với thành viên tĩnh hoặc nguyên mẫu của lớp đối với thành viên thể hiện
- Tên của thành viên
LƯU Ý Bộ mô tả thuộc tính không được cung cấp làm đối số cho bộ trang trí thuộc tính do cách khởi tạo bộ trang trí thuộc tính trong TypeScript. Điều này là do hiện tại không có cơ chế nào để mô tả thuộc tính thể hiện khi xác định các thành viên của nguyên mẫu và không có cách nào để quan sát hoặc sửa đổi trình khởi tạo cho thuộc tính. Giá trị trả về cũng bị bỏ qua. Như vậy, một trình trang trí thuộc tính chỉ có thể được sử dụng để quan sát rằng một thuộc tính của một tên cụ thể đã được khai báo cho một lớp
Chúng tôi có thể sử dụng thông tin này để ghi lại siêu dữ liệu về thuộc tính, như trong ví dụ sau
5
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Sau đó, chúng ta có thể định nghĩa hàm trang trí
20 và hàmts
function sealed[target] {
// do something with 'target' ...
}
21 bằng cách sử dụng các khai báo hàm sauts
function sealed[target] {
// do something with 'target' ...
}
6
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Trang trí
22 ở đây là một nhà máy trang trí. Khits
function sealed[target] {
// do something with 'target' ...
}
22 được gọi, nó sẽ thêm một mục nhập siêu dữ liệu cho thuộc tính bằng cách sử dụng hàmts
function sealed[target] {
// do something with 'target' ...
}
24 từ thư việnts
function sealed[target] {
// do something with 'target' ...
}
25. Khits
function sealed[target] {
// do something with 'target' ...
}
21 được gọi, nó sẽ đọc giá trị siêu dữ liệu cho định dạngts
function sealed[target] {
// do something with 'target' ...
}
LƯU Ý Ví dụ này yêu cầu thư viện
25. Xem Siêu dữ liệu để biết thêm thông tin về thư việnts
function sealed[target] {
// do something with 'target' ...
}
25ts
function sealed[target] {
// do something with 'target' ...
}
Trình trang trí thông số
Trình trang trí tham số được khai báo ngay trước khi khai báo tham số. Trình trang trí tham số được áp dụng cho hàm cho hàm tạo lớp hoặc khai báo phương thức. Không thể sử dụng trình trang trí tham số trong tệp khai báo, quá tải hoặc trong bất kỳ ngữ cảnh xung quanh nào khác [chẳng hạn như trong lớp
0]ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
Biểu thức cho trình trang trí tham số sẽ được gọi là một hàm trong thời gian chạy, với ba đối số sau
- Hàm khởi tạo của lớp đối với thành viên tĩnh hoặc nguyên mẫu của lớp đối với thành viên thể hiện
- Tên của thành viên
- Chỉ số thứ tự của tham số trong danh sách tham số của hàm
LƯU Ý Chỉ có thể sử dụng một trình trang trí tham số để quan sát xem một tham số đã được khai báo trên một phương thức hay chưa
Giá trị trả về của trình trang trí tham số bị bỏ qua
Sau đây là một ví dụ về trình trang trí tham số [
30] được áp dụng cho tham số của một thành viên của lớpts
function sealed[target] {
// do something with 'target' ...
}
2ts
function color[value: string] {
// this is the decorator factory, it sets up
// the returned decorator function
return function [target] {
// this is the decorator
// do something with 'target' and 'value'...
};
}
7
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Sau đó, chúng ta có thể xác định các trình trang trí
30 vàts
function sealed[target] {
// do something with 'target' ...
}
33 bằng cách sử dụng các khai báo hàm sauts
function sealed[target] {
// do something with 'target' ...
}
8
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Trình trang trí
30 thêm mục nhập siêu dữ liệu đánh dấu tham số theo yêu cầu. Trình trang tríts
function sealed[target] {
// do something with 'target' ...
}
33 sau đó bao bọc phương thứcts
function sealed[target] {
// do something with 'target' ...
}
36 hiện có trong một hàm xác thực các đối số trước khi gọi phương thức ban đầuts
function sealed[target] {
// do something with 'target' ...
}
LƯU Ý Ví dụ này yêu cầu thư viện
25. Xem Siêu dữ liệu để biết thêm thông tin về thư việnts
function sealed[target] {
// do something with 'target' ...
}
25ts
function sealed[target] {
// do something with 'target' ...
}
Metadata
Một số ví dụ sử dụng thư viện
25 bổ sung một polyfill cho API siêu dữ liệu thử nghiệm. Thư viện này chưa phải là một phần của tiêu chuẩn ECMAScript [JavaScript]. Tuy nhiên, khi các công cụ trang trí được chính thức áp dụng như một phần của tiêu chuẩn ECMAScript, các tiện ích mở rộng này sẽ được đề xuất áp dụngts
function sealed[target] {
// do something with 'target' ...
}
Bạn có thể cài đặt thư viện này qua npm
9
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
TypeScript bao gồm hỗ trợ thử nghiệm để phát ra một số loại siêu dữ liệu nhất định cho các khai báo có trang trí. Để kích hoạt hỗ trợ thử nghiệm này, bạn phải đặt tùy chọn trình biên dịch
70 trên dòng lệnh hoặc trongts
function sealed[target] {
// do something with 'target' ...
}
5 của bạnts
function sealed[target] {
// do something with 'target' ...
}
Dòng lệnh
0ts
function sealed[target] {
// do something with 'target' ...
}
tsconfig. json
1ts
function sealed[target] {
// do something with 'target' ...
}
Khi được bật, miễn là thư viện
25 đã được nhập, thông tin loại thời gian thiết kế bổ sung sẽ được hiển thị khi chạyts
function sealed[target] {
// do something with 'target' ...
}
Chúng ta có thể thấy điều này trong hành động trong ví dụ sau
2ts
function sealed[target] {
// do something with 'target' ...
}
Trình biên dịch TypeScript sẽ chèn thông tin kiểu thời gian thiết kế bằng cách sử dụng trình trang trí
73. Bạn có thể coi nó tương đương với TypeScript sauts
function sealed[target] {
// do something with 'target' ...
}
3ts
function sealed[target] {
// do something with 'target' ...
}
LƯU Ý Siêu dữ liệu của Trình trang trí là một tính năng thử nghiệm và có thể giới thiệu những thay đổi đột phá trong các bản phát hành trong tương lai
Thuộc tính Python có thể lấy đối số không?
Tạo thuộc tính với thuộc tính[] Bạn có thể tạo thuộc tính bằng cách gọi thuộc tính[] với một bộ đối số thích hợp và gán giá trị trả về của nó cho thuộc tính lớp. Tất cả các đối số của thuộc tính[] là tùy chọn .Các đối tượng có thể được truyền dưới dạng đối số Python không?
Một hàm có thể nhận nhiều đối số, các đối số này có thể là đối tượng, biến [cùng hoặc khác kiểu dữ liệu] và hàm .Sự khác biệt giữa thuộc tính và thuộc tính trong Python là gì?
Các thuộc tính được mô tả bởi các biến dữ liệu, ví dụ như tên, tuổi, chiều cao, v.v. Thuộc tính là loại thuộc tính đặc biệt có các phương thức getter, setter và delete như các phương thức __get__, __set__ và __delete__.Các đối số được truyền theo giá trị hoặc theo tham chiếu như thế nào?
Khi bạn chuyển một đối số bằng tham chiếu, bạn chuyển một con trỏ tới giá trị trong bộ nhớ . Hàm hoạt động trên đối số. Khi một hàm thay đổi giá trị của một đối số được truyền bởi tham chiếu, giá trị ban đầu sẽ thay đổi. Khi bạn chuyển một đối số theo giá trị, bạn chuyển một bản sao của giá trị đó vào bộ nhớ.