Property trong TypeScript
1. Field là gì?
Trong bài học này chúng ta sẽ thảo luận về property trong TypeScript, nhưng trước khi đi vào nội dung chính chúng ta cần làm rõ khái niệm trường (field).
Trường (field) là một biến được khai báo trực tiếp trong một lớp.
Xem thêm bài viết về constructor để hiểu cách TypeScript gán giá trị cho các trường:
Trong ngôn ngữ TypeScript, nếu bạn có thể truy cập vào một trường, bạn có thể lấy ra giá trị của nó và sét giá trị mới cho nó, chẳng hạn như ví dụ sau:
field_ex1.ts
class Person {
name: string;
gender: string;
country?: string; // Allow null value.
// Constructor
constructor(name: string, gender: string, country?: string) {
this.name = name;
this.gender = gender;
this.country = country;
}
// Method:
selfIntroduce(): void {
if (this.country) {
console.log(`Hi, My name is ${this.name}, from ${this.country}`);
} else {
console.log(`Hi, My name is ${this.name}`);
}
}
}
function field_ex1_test() {
var emma: Person = new Person('Emma', 'Female', 'USA'); // Create an object
emma.selfIntroduce(); // Call method.
var name = emma.name; // get the value of a field
console.log(`emma.name: ${name}`);
console.log(`emma.gender: ${emma.gender}`);
console.log(`emma.country: ${emma.country}`);
console.log(` --- Set new value to country field ---: `);
emma.country = 'Canada'; // set new value to a field
console.log(`emma.country: ${emma.country}`);
}
// Call the function.
field_ex1_test();
Output:
Hi, My name is Emma, from USA
emma.name: Emma
emma.gender: Female
emma.country: USA
--- Set new value to country field ---:
emma.country: Canada
2. Private, Protected & Public Fields
TypeScript cũ hơn 3.8
TypeScript cũ hơn 3.8 chưa cung cấp từ khoá private, protected và public. Để có một trường private field các lập trình viên đặt tên cho nó bắt đầu bởi ký tự thăng ( # ). Những trường này chỉ có thể được truy cập bên trong lớp đã định nghĩa ra nó.
field_private_ex1.ts
class Foo {
#bar: string;
constructor(bar: string) {
this.#bar = bar;
}
}
function field_private_ex1_test() {
var foo: Foo = new Foo('Bar'); // Create an object
foo.#bar; // Compile Error!!!!!!
}
TypeScript 3.8+
Bắt đầu từ phiên bản 3.8, TypeScript hỗ trợ từ khoá private, protected và public trong khai báo một trường.
class Class_Name {
private field1: string;
protected field2 : string;
public field3 : string;
field4 : string; // Default = public
}
Modifier | Description |
private | Trường chỉ có thể được truy cập trong lớp đã định nghĩa ra nó. |
protected | Trường có thể được truy cập trong lớp đã định nghĩa ra nó, hoặc trong các lớp con. |
public | Trường có thể được truy cập tại mọi nơi. |
Trong ví dụ dưới đây, một trường được khai báo với từ khoá private, nó không thể được truy cập bên ngoài lớp đã định nghĩa ra nó.
field_private_ex2.ts
class Bar {
private foo: string;
constructor(foo: string) {
this.foo = foo;
}
}
function field_private_ex2_test() {
var bar: Bar = new Bar('Foo'); // Create an object
bar.foo; // Compile Error!!!!!!
}
3. Property là gì?
Về cơ bản, một khi bạn có thể tiếp cận một trường tại một nơi nào đó, bạn có thể lấy ra giá trị của nó và gán giá trị mới cho nó.
Property là một khái niệm tương tự như trường (field), nhưng nó có các tính năng đặc biệt hơn. Property được chia làm 3 loại:
- Read-only Property: Cho phép truy cập vào giá trị của nó, nhưng không cho phép sét giá trị mới cho nó.
- Write-only Property: Cho phép sét giá trị mới cho nó. Tuy nhiên, việc cố gắng truy cập vào property này sẽ nhận được giá trị undefined.
- Read/Write Property: Cho phép truy cập vào giá trị hiện tại và sét giá trị mới cho nó.
Theo ý tưởng thiết kế của TypeScript, bạn nên khai báo tất cả các trường trong lớp với từ khoá private, và sử dụng các property để thay thế vai trò của các trường trong việc giao tiếp với bên ngoài.
4. Getter
Cú pháp Getter cho phép bạn định nghĩa một property cho phép truy cập vào giá trị của nó, nhưng không thể sét giá trị mới cho nó trừ khi bạn cũng định nghĩa Setter cho property này.
Cú pháp:
get property_name(): data_type {
// code ...
return a_value;
}
// Or:
[private, protected, public] get property_name(): data_type {
// code ...
return a_value;
}
Ví dụ: Lớp Employee dưới đây cho phép truy cập vào giá trị của property empId, nhưng không cho phép thay đổi giá trị của property này.
property_getter_ex1.ts
class Employee {
private _empId: number; // Field
empName: string; // Field
dept?: string; // Field
constructor(empId: number, empName: string, dept: string) {
this._empId = empId;
this.empName = empName;
this.dept = dept;
}
// Getter
get empId(): number { // Property - empId
return this._empId;
}
// Method:
showInfo(): void {
if (this.dept) {
console.log(`Emp ID: ${this._empId}, Emp Name: ${this.empName}, Dept: ${this.dept}`);
} else {
console.log(`Emp ID: ${this._empId}, Emp Name: ${this.empName}`);
}
}
}
function property_getter_ex1_test() {
var tom: Employee = new Employee(2, "Tom", "IT"); // Create an object
tom.showInfo(); // Call method.
var empId = tom.empId; // get the value of a property
console.log(`empId: ${empId}`);
// Can not set new value to property - empId
tom.empId = 2; // Compile Error!!!!!!!!!!!!!!!!!!!
}
// Call the function
property_getter_ex1_test();
Bạn có thể sử dụng từ khoá private, protected hoặc public trong định nghĩa Getter.
// Getter
protected get empId(): number { // Property - empId
return this._empId;
}
5. Setter
Cú pháp Setter cho phép bạn định nghĩa một property cho phép gán giá trị mới cho nó. Tuy nhiên, nếu không có Getter, việc cố gắng truy cập vào property này sẽ nhận được giá trị underfined.
Cú pháp:
set property_name(new_value: data_type) {
// code ...
}
// Or:
[private, protected, public] set property_name(new_value: data_type) {
// code ...
}
Ví dụ: Lớp Staff có Setter nhưng không có Getter cho property salary. Nếu bạn cố gắng truy cập vào giá trị của salary trình biên dịch sẽ không thông báo lỗi, nhưng giá trị nhận được là undefined.
property_setter_ex1.ts
class Staff {
private _staffId: number; // Field
staffName: string; // Field
private _salary?: number; // Field
constructor(staffId: number, staffName: string, salary: number) {
this._staffId = staffId;
this.staffName = staffName;
this._salary = salary;
}
// Getter
get staffId(): number { // Property - staffId
return this._staffId;
}
// Setter
set salary(salary: number) {
this._salary = salary;
}
showInfo() {
console.log(`ID: ${this._staffId}, Name: ${this.staffName}, Salary: ${this._salary}`)
}
}
function property_setter_ex1_test() {
var tom: Staff = new Staff(2, "Tom", 2000); // Create an object
tom.showInfo();
tom.salary = 3000; // Set new value to salary property
tom.showInfo();
// Try to access to 'salary' property of Staff class
console.log(" --- Try to access to 'salary' property of Staff class --- ");
var s = tom.salary; // No problem at Compile Time (!!!!!!!!!!!)
console.log(`tom.salary = ${s}`); // underfined (!!!!!!!!!!!!!!!)
}
// Call the function
property_setter_ex1_test();
Output:
ID: 2, Name: Tom, Salary: 2000
ID: 2, Name: Tom, Salary: 3000
--- Try to access to 'salary' property of Staff class ---
tom.salary = undefined
Bạn có thể sử dụng từ khoá private, protected hoặc public trong định nghĩa Setter, ý nghĩa của nó tương tự như việc sử dụng với các trường.
// Setter
public set salary(salary: number) {
this._salary = salary;
}
Các hướng dẫn TypeScript
- Chạy ví dụ TypeScript đầu tiên của bạn trong Visual Studio Code
- Không gian tên (Namespace) trong TypeScript
- Module trong TypeScript
- Toán tử typeof trong TypeScript
- Biến (Variable) trong TypeScript
- Vòng lặp trong TypeScript
- Cài đặt TypeScript trên Windows
- Hướng dẫn và ví dụ hàm trong TypeScript
- Tuples trong TypeScript
- Interface trong TypeScript
- Mảng (Array) trong TypeScript
- Toán tử instanceof trong TypeScript
- Phương thức trong TypeScript
- Hướng dẫn và ví dụ TypeScript Closures
- Constructor trong TypeScript
- Property trong TypeScript
- Phân tích JSON trong TypeScript
- Phân tích JSON trong TypeScript với thư viện json2typescript
- Trình chuyển đổi mã nguồn (Transpiler) là gì?
Show More