JavaScript: JavaScript Private Fields


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Tổng quan

Trong quá trình phát triển ứng dụng, việc bảo vệ dữ liệu và đảm bảo tính an toàn của mã nguồn là vô cùng quan trọng. Trường private trong JavaScript cho phép chúng ta giới hạn truy cập vào dữ liệu và phương thức, tạo ra mã dễ bảo trì và linh hoạt hơn. Trong bài viết này, chúng ta sẽ đi sâu vào cách thực hiện trường private , các kỹ thuật tiếp cận và lợi ích của việc sử dụng chúng.

Giới thiệu về JavaScript Private Fields

ES2022 cho phép bạn xác định các JavaScript Private Fields cho một lớp . Để xác định một private field, thêm dấu # vào trước tên field (trường).

Ví dụ: đoạn mã sau đây định nghĩa lớp Circle có trường private radius:

class Circle {
  #radius;
  constructor(value) {
    this.#radius = value;
  }
  get area() {
    return Math.PI * Math.pow(this.#radius, 2);
  }
}

Trong ví dụ trên:

  • Đầu tiên, xác định trường private #radius trong nội dung lớp.
  • Thứ hai, khởi tạo trường #radius trong hàm tạo bằng một đối số.
  • Thứ ba, tính diện tích hình tròn bằng cách truy cập vào trường private #radius trong phương thức getter

Phần sau đây tạo một đối tượng mới của lớp Circle và tính diện tích của nó:

let circle = new Circle(10);
console.log(circle.area); // 314.1592653589793

Vì #radius là trường private nên bạn chỉ có thể truy cập nó trong lớp Circle. Nói cách khác, #radius là không thể truy cập từ bên ngoài lớp Circle.

Sử dụng getter và setter để truy cập các trường private

Đoạn mã sau đây định nghĩa lại lớp Circle bằng cách thêm getter và setter của radius để cung cấp quyền truy cập vào #radius:

class Circle {
  #radius = 0;
  constructor(radius) {
    this.radius = radius; // calling setter
  }
  get area() {
    return Math.PI * Math.pow(this.#radius, 2);
  }
  set radius(value) {
    if (typeof value === 'number' && value > 0) {
      this.#radius = value;
    } else {
      throw 'The radius must be a positive number';
    }
  }
  get radius() {
    return this.#radius;
  }
}
  • Radius setter thiết lập xác thực đối số trước khi gán nó vào trường private #radius. Nếu đối số không phải là số dương thì radius setter sẽ báo lỗi.
  • Radius getter trả về giá trị của #radius.
  • Hàm tạo gọi radius setter để gán đối số cho #radius.

Các trường private chỉ có thể truy cập được bên trong lớp nơi chúng được định nghĩa. Ngoài ra, chúng không thể truy cập được từ các lớp con. Ví dụ: đoan mã sau định nghĩa lớp Cylinder là lớp con của lớp Circle:

class Cylinder extends Circle {
  #height;
  constructor(radius, height) {
    super(radius);
    this.#height = height;
    // cannot access the #radius of the Circle class here
  }
}

Nếu cố gắng truy cập vào trường private #radius trong lớp Cylinder, bạn sẽ nhận được lỗi SyntaxError.

Toán tử in

Để kiểm tra xem một đối tượng có trường private bên trong một lớp hay không, bạn sử dụng toán tử in:

fieldName in objectName

Ví dụ: đoạn mã sau đây thêm phương thức tĩnh hasRadius() vào lớp Circle sử dụng toán tử in để kiểm tra xem đối tượng circle có trường private #radius hay không:

class Circle {
  #radius = 0;
  constructor(radius) {
    this.radius = radius;
  }
  get area() {
    return Math.PI * Math.pow(this.radius, 2);
  }
  set radius(value) {
    if (typeof value === 'number' && value > 0) {
      this.#radius = value;
    } else {
      throw 'The radius must be a positive number';
    }
  }
  get radius() {
    return this.#radius;
  }
  static hasRadius(circle) {
    return #radius in circle;
  }
}

let circle = new Circle(10);

console.log(Circle.hasRadius(circle)); // true

Các trường private tĩnh

Ví dụ sau đây cho thấy cách sử dụng trường private tĩnh:

class Circle {
  #radius = 0;
  static #count = 0;
  constructor(radius) {
    this.radius = radius; // calling setter
    Circle.#count++;
  }
  get area() {
    return Math.PI * Math.pow(this.radius, 2);
  }
  set radius(value) {
    if (typeof value === 'number' && value > 0) {
      this.#radius = value;
    } else {
      throw 'The radius must be a positive number';
    }
  }
  get radius() {
    return this.#radius;
  }
  static hasRadius(circle) {
    return #radius in circle;
  }
  static getCount() {
    return Circle.#count;
  }
}
let circles = [new Circle(10), new Circle(20), new Circle(30)];
console.log(Circle.getCount());

Giải thích

Đầu tiên, thêm một trường tĩnh private #count vào lớp Circle và khởi tạo giá trị của nó là 0:

static #count = 0;

Thứ hai, tăng #count thêm một trong hàm khởi tạo:

Circle.#count++;

Thứ ba, xác định một phương thức tĩnh trả về giá trị của #count:

static getCount() {
    return Circle.#count;
}

Cuối cùng, tạo ba đối tượng của lớp Circle và xuất giá trị count ra console:

let circles = [new Circle(10), new Circle(20), new Circle(30)];
console.log(Circle.getCount()); // 3

Tóm tắt

  • Tiền tố tên trường có để đặt nó ở chế độ private.
  • Các trường private chỉ có thể truy cập được bên trong lớp chứ không phải từ bên ngoài lớp hoặc các lớp con.
  • Sử dụng toán tử in để kiểm tra xem một đối tượng có trường private hay không.
» Tiếp: JavaScript Private Methods
« Trước: IIFE - Hàm gọi ngay
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!