JavaScript: JavaScript Reflection


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

Reflection là gì

Trong lập trình máy tính, reflection là khả năng của một chương trình để thao tác các biến, thuộc tính và phương thức của các đối tượng tại thời gian chạy.

Trước ES6, JavaScript đã có các tính năng reflection dù cộng đồng hay đặc tả kỹ thuật không chính thức gọi chúng như vậy. Ví dụ, các phương thức như Object.keys(), Object.getOwnPropertyDescriptor(), và Array.isArray() là các tính năng reflection cổ điển.

ES6 giới thiệu một đối tượng toàn cục mới gọi là Reflect, cho phép bạn gọi các phương thức, tạo đối tượng, lấy và thiết lập các thuộc tính, và thao tác và mở rộng các thuộc tính.

API Reflect quan trọng vì nó cho phép bạn phát triển các chương trình và khung làm việc có khả năng xử lý mã động.

Reflect API

Không giống như hầu hết các đối tượng toàn cục, Reflect không phải là một constructor. Điều đó có nghĩa là bạn không thể sử dụng toán tử new hoặc gọi the Reflect như một hàm. Nó tương tự như các đối tượng Math hay JSON. Tất cả các phương thức của đối tượng  Reflect đều là static.

Reflect.apply()– gọi một hàm với các đối số được chỉ định.

  • Reflect.construct()– hoạt động như toán tử new, nhưng như một hàm. Nó tương đương với việc gọi new target(...args).
  • Reflect.defineProperty()– tương tự như Object.defineProperty(), nhưng trả về giá trị Boolean cho biết thuộc tính có được xác định thành công trên đối tượng hay không.
  • Reflect.deleteProperty()– hoạt động như toán tử delete, nhưng như một hàm. Tương đương với việc gọi  delete objectName[propertyName].
  • Reflect.get()– trả về giá trị của một thuộc tính.
  • Reflect.getOwnPropertyDescriptor()– tương tự như Object.getOwnPropertyDescriptor(). Nó trả về một mô tả thuộc tính của một thuộc tính nếu thuộc tính đó tồn tại trên đối tượng hoặc undefined nếu ngược lại.
  • Reflect.getPrototypeOf()– giống như Object.getPrototypeOf().
  • Reflect.has()– hoạt động như intoán tử, nhưng như một hàm. Nó trả về giá trị boolean cho biết liệu một thuộc tính (sở hữu hoặc thừa kế) có tồn tại hay không.
    Reflect.isExtensible()– giống như Object.isExtensible().
  • Reflect.ownKeys()– trả về một mảng các khóa thuộc tính được sở hữu (không được kế thừa) của một đối tượng.
  • Reflect.preventExtensions()– tương tự như Object.preventExtensions(). Nó trả về một Boolean.
  • Reflect.set()– gán giá trị cho thuộc tính và trả về giá trị Boolean, giá trị này là true nếu thuộc tính được thiết lập thành công.
  • Reflect.setPrototypeOf()– thiết lập nguyên mẫu của đối tượng

Ví dụ

Tạo đối tượng: Reflect.construct()

Phương thức Reflect.construct()hoạt động giống như toán tử new, nhưng là một hàm. Nó tương đương với việc gọi the new target(...args)với khả năng chỉ định một nguyên mẫu khác:

Reflect.construct(target, args [, newTarget])

Phương thức Reflect.construct() trả về thể hiện mới của đối tượng target, hoặc newTarget nếu được chỉ định, được khởi tạo bởi target như một hàm khởi tạo với đối tượng dạng mảng args được cung cấp. Xem ví dụ sau:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    get fullName() {
        return `${this.firstName} ${this.lastName}`;
    }
};

let args = ['John', 'Doe'];

let john = Reflect.construct(
    Person,
    args
);

console.log(john instanceof Person);
console.log(john.fullName); // John Doe

Output

true
John Doe

Trong ví dụ này:

  • Đầu tiên,  định nghĩa một lớp có tên là Person.
  • Thứ hai, khai báo một mảng args chứa hai chuỗi.
  • Thứ ba, tạo một thể hiện mới của lớp Person bằng phương thức Reflect.construct(). Đối tượng john là một thể hiện của lớp Person nên có thuộc tính fullName.

Gọi một hàm: Reflect.apply()

Trước ES6, bạn gọi một hàm với giá trị this được chỉ định và arguments bằng cách sử dụng phương thức Function.prototype.apply(). Ví dụ:

let result = Function.prototype.apply.call(Math.max, Math, [10, 20, 30]);
console.log(result);

Output

30

Reflect.apply() cung cấp các tính năng tương tự như Function.prototype.apply() nhưng ít dài dòng hơn và dễ hiểu hơn:

let result = Reflect.apply(Math.max, Math, [10, 20, 30]);
console.log(result);

Sau đây là cú pháp của phương thức Reflect.apply():

Reflect.apply(target, thisArg, args)

Định nghĩa một thuộc tính:Reflect.defineProperty()

Reflect.defineProperty() giống như Object.defineProperty(). Tuy nhiên, nó trả về Boolean cho biết thuộc tính đã được định nghĩa thành công hay chưa thay vì đưa ra ngoại lệ:

Reflect.defineProperty(target, propertyName, propertyDescriptor)

Xem ví dụ sau:

let person = {
    name: 'John Doe'
};

if (Reflect.defineProperty(person, 'age', {
        writable: true,
        configurable: true,
        enumerable: false,
        value: 25,
    })) {
    console.log(person.age);
} else {
    console.log('Cannot define the age property on the person object.');
}
» Tiếp: Đối tượng di chuyển theo chuột
« Trước: JavaScript Factory Functions
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 !!!