Gunakan kasing: #
bidang -private
Kata pengantar:
Privasi waktu kompilasi dan run-time
#
bidang -private menyediakan privasi waktu kompilasi dan run-time, yang tidak "bisa diretas". Ini adalah mekanisme untuk mencegah akses ke anggota dari luar badan kelas dengan cara langsung apa pun .
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.
Warisan kelas yang aman
#
Bidang -private mendapatkan cakupan yang unik. Hirarki kelas dapat diimplementasikan tanpa ditimpa secara tidak sengaja properti pribadi dengan nama yang sama.
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"
Kompiler TS untungnya memancarkan kesalahan, ketika private
properti dalam bahaya ditimpa (lihat contoh ini ). Tetapi karena sifat fitur kompilasi-waktu semuanya masih mungkin pada saat dijalankan, mengingat kesalahan kompilasi diabaikan dan / atau kode JS yang dipancarkan digunakan.
Perpustakaan eksternal
Penulis perpustakaan dapat melakukan refactor #
pengidentifikasi pribadi tanpa menyebabkan perubahan besar bagi klien. Pengguna perpustakaan di sisi lain dilindungi dari mengakses bidang internal.
API JS menghilangkan #
bidang -private
Fungsi dan metode JS #
bawaan mengabaikan bidang -privat. Ini dapat menghasilkan pemilihan properti yang lebih mudah diprediksi pada saat run-time. Contoh: Object.keys
, Object.entries
, JSON.stringify
, for..in
lingkaran dan lain-lain ( kode contoh , lihat juga Matt Bierner ini jawaban ):
class Foo {
#bar = 42;
baz = "huhu";
}
Object.keys(new Foo()); // [ "baz" ]
Gunakan kasus: private
kata kunci
Kata pengantar:
Akses ke API kelas internal dan status (kompilasi waktu saja privasi)
private
anggota kelas adalah properti konvensional pada saat run-time. Kita dapat menggunakan fleksibilitas ini untuk mengakses API internal kelas atau status dari luar. Untuk memenuhi pemeriksaan kompiler, mekanisme seperti jenis pernyataan, akses properti dinamis atau @ts-ignore
dapat digunakan antara lain.
Contoh dengan jenis pernyataan ( as
/ <>
) dan any
tugas variabel yang diketik:
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 bahkan memungkinkan akses properti dinamis dari private
anggota dengan jalan keluar :
class C {
private foo = 10;
}
const res = new C()["foo"]; // 10, res has type number
Di mana akses pribadi masuk akal? (1) tes unit, (2) situasi debugging / logging atau (3) skenario kasus lanjutan lainnya dengan kelas proyek-internal (daftar terbuka).
Akses ke variabel internal agak kontradiktif - jika tidak, Anda tidak akan membuatnya private
di tempat pertama. Sebagai contoh, pengujian unit seharusnya berupa kotak hitam / abu-abu dengan bidang pribadi disembunyikan sebagai detail implementasi. Namun dalam praktiknya, mungkin ada pendekatan yang valid dari kasus ke kasus.
Tersedia di semua lingkungan ES
private
Pengubah TS dapat digunakan dengan semua target ES. #
Bidang -private hanya tersedia untuk target
ES2015
/ ES6
atau lebih tinggi. Dalam ES6 +, WeakMap
digunakan secara internal sebagai implementasi tingkat bawah (lihat di sini ). Asli #
bidang-swasta saat ini membutuhkan target
esnext
.
Konsistensi dan kompatibilitas
Tim mungkin menggunakan pedoman pengkodean dan aturan linter untuk menegakkan penggunaan private
sebagai satu-satunya pengubah akses. Pembatasan ini dapat membantu dengan konsistensi dan menghindari kebingungan dengan #
notasi bidang -private dengan cara yang kompatibel dengan mundur.
Jika diperlukan, properti parameter (singkatan penugasan konstruktor) adalah penghenti acara. Mereka hanya dapat digunakan dengan private
kata kunci dan tidak ada rencana untuk mengimplementasikannya untuk #
bidang -privat.
Alasan lain
private
mungkin memberikan kinerja run-time yang lebih baik dalam beberapa kasus down-leveling (lihat di sini ).
- Tidak ada metode kelas privat keras yang tersedia di TS hingga saat ini.
- Beberapa orang menyukai
private
notasi kata kunci yang lebih baik 😊.
Perhatikan keduanya
Kedua pendekatan menciptakan semacam jenis nominal atau merek pada waktu kompilasi.
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
Juga, keduanya memungkinkan akses lintas-instance: instance dari kelas A
dapat mengakses anggota pribadi dari A
instance lain :
class A {
private a = 0;
method(arg: A) {
console.log(arg.a); // works
}
}
Sumber