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 privateproperti 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..inlingkaran dan lain-lain ( kode contoh , lihat juga Matt Bierner ini jawaban ):
class Foo {
#bar = 42;
baz = "huhu";
}
Object.keys(new Foo()); // [ "baz" ]
Gunakan kasus: privatekata kunci
Kata pengantar:
Akses ke API kelas internal dan status (kompilasi waktu saja privasi)
privateanggota 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-ignoredapat digunakan antara lain.
Contoh dengan jenis pernyataan ( as/ <>) dan anytugas 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 privateanggota 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 privatedi 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
privatePengubah TS dapat digunakan dengan semua target ES. #Bidang -private hanya tersedia untuk target ES2015/ ES6atau lebih tinggi. Dalam ES6 +, WeakMapdigunakan 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 privatekata kunci dan tidak ada rencana untuk mengimplementasikannya untuk #bidang -privat.
Alasan lain
privatemungkin 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
privatenotasi 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 Adapat mengakses anggota pribadi dari Ainstance lain :
class A {
private a = 0;
method(arg: A) {
console.log(arg.a); // works
}
}
Sumber