Symbol
Symbol là một kiểu dữ liệu nguyên thủy trong JavaScript, có tính chất đặc biệt là giá trị của kiểu này có thể được sử dụng để tạo ra các thuộc tính vô danh cho đối tượng.
Đặc điểm của kiểu dữ liệu
Kiểm tra kiểu dữ liệu
Giá trị Symbol chỉ có thể được tạo ra bằng cách sử dụng hàm Symbol. Giá trị của kiểu Symbol khi được sử dụng làm tên thuộc tính cho đối tượng đảm bảo không xảy ra xung đột với tên thuộc tính khác.
Không thể khởi tạo đối tượng
Lưu ý rằng không thể sử dụng lệnh new
để khởi tạo đối tượng trước hàm Symbol, nếu không sẽ gây ra lỗi. Điều này là do giá trị Symbol được tạo ra là một giá trị nguyên thủy, không phải là một đối tượng. Nó tương tự như một kiểu dữ liệu như chuỗi.
Kiểm tra nguyên mẫu
Sử dụng instanceof
để kiểm tra mối quan hệ giữa một thể hiện và Symbol.
Mô tả thể hiện
Hàm Symbol có thể nhận một chuỗi làm tham số, đại diện cho mô tả của thể hiện Symbol. Mục đích chính là để hiển thị trên bảng điều khiển hoặc khi chuyển đổi thành chuỗi để dễ dàng phân biệt.
Nếu tham số của Symbol là một đối tượng, nó sẽ gọi phương thức toString
của đối tượng đó để chuyển đổi thành chuỗi, sau đó mới tạo ra một giá trị Symbol.
Mô tả giống nhau
Lưu ý rằng tham số của hàm Symbol
chỉ đại diện cho mô tả của giá trị Symbol hiện tại, do đó giá trị trả về của hai hàm Symbol
với cùng một tham số sẽ không bằng nhau.
Phép toán và chuyển đổi kiểu dữ liệu
Giá trị Symbol không thể thực hiện phép toán với các kiểu dữ liệu khác, sẽ gây ra lỗi.
Tuy nhiên, giá trị Symbol có thể được chuyển đổi thành chuỗi một cách rõ ràng.
Ngoài ra, giá trị Symbol cũng có thể chuyển đổi thành giá trị boolean, nhưng không thể chuyển đổi thành giá trị số.
Tên thuộc tính của đối tượng
Vì mỗi giá trị Symbol là không đồng nhất, điều này có nghĩa là giá trị Symbol có thể được sử dụng làm định danh, để làm tên thuộc tính cho đối tượng, đảm bảo không có thuộc tính trùng tên. Điều này rất hữu ích trong trường hợp một đối tượng được tạo bởi nhiều mô-đun khác nhau, để tránh việc ghi đè hoặc che đậy một thuộc tính không cần thiết.
Trong công việc thực tế, chắc chắn sẽ thường xuyên sử dụng các thư viện của người khác, và sau đó, vì không biết tên thuộc tính của một đối tượng nào đó, ta sẽ vô tình ghi đè lên một thuộc tính của đối tượng đó, dẫn đến các lỗi không cần thiết. Nhưng với kiểu dữ liệu Symbol, ta có thể dễ dàng tránh được những sai lầm như vậy.
⚠️ Lưu ý, khi sử dụng giá trị Symbol làm tên thuộc tính của đối tượng, không thể sử dụng toán tử chấm.
Trong đoạn mã trên, vì sau toán tử chấm luôn là một chuỗi, nên nó không đọc sym
như một tên định danh của giá trị Symbol, dẫn đến tên thuộc tính của a
thực tế là một chuỗi, không phải là một giá trị Symbol.
Tương tự, khi định nghĩa thuộc tính bằng giá trị Symbol bên trong đối tượng, giá trị Symbol phải được đặt trong dấu ngoặc vuông.
Có thể sử dụng cú pháp viết tắt cho đối tượng.
kiểu dữ liệu Symbol cũng có thể được sử dụng để định nghĩa một nhóm hằng số, đảm bảo các giá trị hằng số này là không đồng nhất.
Cần lưu ý rằng, khi giá trị Symbol được sử dụng làm tên thuộc tính, thuộc tính đó vẫn là một thuộc tính công khai, không phải là thuộc tính riêng tư.
Không thể liệt kê
Khi Symbol được sử dụng làm tên thuộc tính, thuộc tính đó sẽ không xuất hiện trong vòng lặp for…in
, for…of
, cũng không được trả về bởi các phương thức Object.keys()
, Object.getOwnPropertyNames()
, JSON.stringify()
.
Tuy nhiên, nó không phải là thuộc tính riêng tư, có một phương thức Object.getOwnPropertySymbols
có thể lấy tất cả các tên thuộc tính Symbol của đối tượng cụ thể.
Phương thức Object.getOwnPropertySymbols
trả về một mảng, thành viên của mảng là các giá trị Symbol được sử dụng làm tên thuộc tính của đối tượng hiện tại.
Phương thức tĩnh
Symbol.for()
Phương thức Symbol.for()
sẽ dựa vào khóa được cung cấp để tìm kiếm trong bảng đăng ký Symbol của thời gian chạy và trả về Symbol tương ứng nếu tìm thấy, nếu không, nó sẽ tạo một Symbol mới liên kết với khóa đó và đưa vào bảng đăng ký Symbol toàn cục.
Cả hai biến trên đều được tạo ra bằng cách sử dụng phương thức Symbol.for
với cùng một tham số, vì vậy thực tế là chúng là cùng một giá trị.
Symbol.for
và Symbol
đều tạo ra một Symbol mới. Sự khác biệt giữa chúng là: Symbol.for
sẽ được đăng ký trong môi trường toàn cục để tìm kiếm, trong khi Symbol
không được đăng ký.
Symbol.for()
không trả về một giá trị Symbol mới mỗi khi được gọi, mà nó sẽ kiểm tra xem khóa đã cho có tồn tại hay không. Nếu không tồn tại, nó sẽ tạo ra một giá trị mới. Nếu tồn tại, nó sẽ trả về cùng một giá trị Symbol.
Symbol.keyFor()
Phương thức Symbol.keyFor
được sử dụng để lấy khóa liên kết với một giá trị Symbol cụ thể trong bảng đăng ký Symbol.
Tham số sym
là một phiên bản Symbol được lưu trữ trong bảng đăng ký Symbol.
⚠️ Lưu ý rằng hàm này được sử dụng để tìm thông tin đăng ký của một giá trị Symbol. Nếu bạn sử dụng hàm Symbol()
để tạo một giá trị Symbol, dù bạn có truyền tham số hay không, bạn sẽ không tìm thấy thông tin đăng ký của nó. Nói cách khác, giá trị Symbol được tạo bằng Symbol()
là không có đăng ký. Nhưng giá trị Symbol được tạo bằng Symbol.for()
sẽ có thông tin đăng ký.
Giá trị tích hợp sẵn
Ngoài các giá trị Symbol do người dùng tự định nghĩa, ES6 còn cung cấp 11 giá trị Symbol tích hợp sẵn, được sử dụng bên trong ngôn ngữ.
- Symbol.hasInstance
- Symbol.isConcatSpreadable
- Symbol.iterator
- Symbol.match
- Symbol.replace
- Symbol.search
- Symbol.species
- Symbol.split
- Symbol.toPrimitive
- Symbol.toStringTag
- Symbol.unscopables
Cài đặt thủ công
Cài đặt thủ công của Symbol:
Không thể cài đặt các tính năng sau:
- Sử dụng
typeof
, kết quả là"symbol"
. Vì chúng ta không thể thay đổi kết quả của toán tửtypeof
trong ES5, nên không thể cài đặt. - Hàm Symbol có thể nhận một chuỗi làm tham số, đại diện cho mô tả của thể hiện Symbol. Điều này không thể cài đặt.
- Giá trị Symbol không thể thực hiện phép toán với các kiểu dữ liệu khác, sẽ gây ra lỗi. Không thể cài đặt tính năng này.
- Giá trị Symbol có thể được chuyển đổi thành chuỗi một cách rõ ràng. Không thể cài đặt tính năng này.
- Khi Symbol được sử dụng làm tên thuộc tính, thuộc tính đó sẽ không xuất hiện trong vòng lặp
for…in
,for…of
, cũng không được trả về bởi các phương thứcObject.keys()
,Object.getOwnPropertyNames()
,JSON.stringify()
. Không thể cài đặt tính năng này.
Tổng kết
- Giá trị Symbol chỉ có thể được tạo ra bằng cách sử dụng hàm
Symbol()
. - Tham số của
Symbol()
chỉ đại diện cho mô tả của giá trị Symbol hiện tại, và việc gọi với cùng một tham số sẽ trả về các giá trị Symbol khác nhau. - Không thể sử dụng lệnh
new
trước hàmSymbol()
. - Tên thuộc tính của đối tượng có thể là giá trị Symbol, giúp tránh xung đột tên thuộc tính.
- Giá trị Symbol không thể sử dụng toán tử chấm để truy cập.
- Có một số ứng dụng của Symbol, ví dụ như sử dụng làm tên thuộc tính để tránh xung đột, hoặc làm các hằng số không trùng lặp.