Trường hợp sử dụng: #
-private trường
Lời nói đầu:
Biên dịch thời gian và gian riêng tư chạy
#
lĩnh vực -private cung cấp thời gian biên dịch và thời gian chạy riêng tư, mà không phải là "hack". Đó là một cơ chế để ngăn chặn truy cập vào một thành viên từ bên ngoài cơ thể lớp theo bất kỳ cách trực tiếp nào .
class A {
#a: number;
constructor(a: number) {
this.#a = a;
}
}
let foo: A = new A(42);
foo.#a; // error, not allowed outside class bodies
(foo as any).#bar; // still nope.
Kế thừa lớp an toàn
#
lĩnh vực -private có được một phạm vi duy nhất. Hệ thống phân cấp lớp có thể được thực hiện mà không cần ghi đè lên các thuộc tính riêng có tên bằng nhau.
class A {
#a = "a";
fnA() { return this.#a; }
}
class B extends A {
#a = "b";
fnB() { return this.#a; }
}
const b = new B();
b.fnA(); // returns "a" ; unique property #a in A is still retained
b.fnB(); // returns "b"
Trình biên dịch TS may mắn phát ra lỗi, khi private
các thuộc tính có nguy cơ bị ghi đè (xem ví dụ này ). Nhưng do bản chất của một tính năng thời gian biên dịch, mọi thứ vẫn có thể xảy ra vào thời gian chạy, các lỗi biên dịch đã cho được bỏ qua và / hoặc mã JS phát ra được sử dụng.
Thư viện bên ngoài
Thư viện tác giả có thể tái cấu trúc #
định danh -private mà không gây ra thay đổi đột phá cho khách hàng. Người dùng thư viện ở phía bên kia được bảo vệ khỏi truy cập vào các trường nội bộ.
Bỏ qua API JS #
các trường -private
Các hàm và phương thức JS tích hợp bỏ qua #
các trường -private. Điều này có thể dẫn đến một lựa chọn tài sản dễ dự đoán hơn vào thời gian chạy. Ví dụ: Object.keys
, Object.entries
, JSON.stringify
, for..in
vòng lặp và những người khác ( mẫu mã ; cũng thấy Matt Bierner của câu trả lời ):
class Foo {
#bar = 42;
baz = "huhu";
}
Object.keys(new Foo()); // [ "baz" ]
Các trường hợp sử dụng: private
từ khóa
Lời nói đầu:
Truy cập vào API lớp nội bộ và trạng thái (chỉ bảo mật thời gian biên dịch)
private
các thành viên của một lớp là các thuộc tính thông thường tại thời gian chạy. Chúng ta có thể sử dụng tính linh hoạt này để truy cập API nội bộ của lớp hoặc trạng thái từ bên ngoài. Để đáp ứng kiểm tra trình biên dịch, các cơ chế như xác nhận kiểu, truy cập thuộc tính động hoặc @ts-ignore
có thể được sử dụng giữa các trình khác.
Ví dụ với xác nhận kiểu ( as
/ <>
) và any
gán biến được gõ:
class A {
constructor(private a: number) { }
}
const a = new A(10);
a.a; // TS compile error
(a as any).a; // works
const casted: any = a; casted.a // works
TS thậm chí còn cho phép truy cập thuộc tính động của một private
thành viên với một lối thoát :
class C {
private foo = 10;
}
const res = new C()["foo"]; // 10, res has type number
Truy cập cá nhân có thể có ý nghĩa ở đâu? (1) kiểm tra đơn vị, (2) gỡ lỗi / ghi nhật ký hoặc (3) các tình huống nâng cao khác với các lớp bên trong dự án (danh sách kết thúc mở).
Truy cập vào các biến nội bộ là một chút mâu thuẫn - nếu không, bạn sẽ không thực hiện chúng private
ở vị trí đầu tiên. Để đưa ra một ví dụ, các bài kiểm tra đơn vị được cho là các hộp đen / xám với các trường riêng được ẩn làm chi tiết triển khai. Trong thực tế, có thể có các cách tiếp cận hợp lệ từ trường hợp này sang trường hợp khác.
Có sẵn trong mọi môi trường ES
Công cụ private
sửa đổi TS có thể được sử dụng với tất cả các mục tiêu ES. #
lĩnh vực -private chỉ có sẵn cho target
ES2015
/ ES6
hoặc cao hơn. Trong ES6 +, WeakMap
được sử dụng nội bộ như triển khai downlevel (xem tại đây ). Các #
lĩnh vực bí mật bản địa hiện đang yêu cầutarget
esnext
.
Tính nhất quán và tương thích
Các nhóm có thể sử dụng các nguyên tắc mã hóa và quy tắc kẻ nói dối để thực thi việc sử dụng private
như là công cụ sửa đổi truy cập duy nhất. Hạn chế này có thể giúp thống nhất và tránh nhầm lẫn với #
ký hiệu trường -private theo cách tương thích ngược.
Nếu được yêu cầu, các thuộc tính tham số (tốc ký gán của hàm tạo) là một nút chặn hiển thị. Chúng chỉ có thể được sử dụng với private
từ khóa và chưa có kế hoạch triển khai chúng cho #
các lĩnh vực -private.
Những lý do khác
private
có thể cung cấp hiệu suất thời gian chạy tốt hơn trong một số trường hợp xuống cấp (xem tại đây ).
- Cho đến nay không có phương pháp lớp học riêng cứng nào có sẵn trong TS.
- Một số người thích
private
ký hiệu từ khóa tốt hơn 😊.
Lưu ý cả hai
Cả hai cách tiếp cận đều tạo ra một số loại danh nghĩa hoặc nhãn hiệu tại thời điểm biên dịch.
class A1 { private a = 0; }
class A2 { private a = 42; }
const a: A1 = new A2();
// error: "separate declarations of a private property 'a'"
// same with hard private fields
Ngoài ra, cả hai đều cho phép truy cập thể hiện chéo: một thể hiện của lớp A
có thể truy cập các thành viên riêng của các A
thể hiện khác :
class A {
private a = 0;
method(arg: A) {
console.log(arg.a); // works
}
}
Nguồn