Ký hiệu là một khái niệm tương đối mới ban đầu được đưa vào trong ES6. Ký hiệu nguyên gốc biểu thị một giá trị duy nhất không bao giờ xung đột với bất kỳ giá trị nào khác, bao gồm cả giá trị của các ký hiệu nguyên gốc khác. Hai chuỗi gốc tạo thành từ các ký tự giống nhau sẽ được đánh giá là nghiêm ngặt bằng:
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
Tuy nhiên, không thể có hai ký hiệu được tạo bằng hàm Symbol()
hoàn toàn ngang bằng:
Symbol() === Symbol()
> false
Trait này cho phép bạn sử dụng các ký hiệu làm khoá thuộc tính duy nhất trong một đối tượng, ngăn chặn xung đột với các khoá mà bất kỳ mã nào khác có thể thêm vào đối tượng đó.
const mySymbol = Symbol( "Desc" );
const myObject = {
}
myObject
> Object { Symbol("Desc"): "propSymbol" }
Có ba loại biểu tượng:
- Biểu tượng được tạo bằng
Symbol()
- Các biểu tượng dùng chung được thiết lập và truy xuất từ sổ đăng ký biểu tượng chung bằng cách sử dụng
Symbol.for()
- "Những biểu tượng nổi tiếng" được xác định là các thuộc tính tĩnh trên đối tượng Symbol (Biểu tượng). Các ký hiệu này chứa phương thức nội bộ không thể vô tình ghi đè.
Symbol()
chấp nhận nội dung mô tả (hoặc "tên biểu tượng") làm đối số không bắt buộc.
Những nội dung mô tả này là nhãn mà con người đọc được để phục vụ cho mục đích gỡ lỗi và
không ảnh hưởng đến tính duy nhất của kết quả. Mọi lệnh gọi đến Symbol
đều trả về một giá trị
biểu tượng hoàn toàn duy nhất, ngay cả khi nhiều lệnh gọi có giống hệt nhau
mô tả:
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
Cũng giống như các kiểu dữ liệu gốc khác, biểu tượng sẽ kế thừa các phương thức và thuộc tính từ nguyên mẫu của chúng. Ví dụ: bạn có thể truy cập vào nội dung mô tả dưới dạng thuộc tính kế thừa của biểu tượng đã tạo:
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
Tuy nhiên, bạn không thể tạo biểu tượng bằng từ khoá new
:
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
Ký hiệu không thể liệt kê được, nghĩa là không có các thuộc tính tượng trưng
khi dùng các phương thức chuẩn để lặp lại các lượt chuyển đổi đó. getOwnPropertySymbols()
phương thức cấp quyền truy cập vào các thuộc tính biểu tượng của một đối tượng.
Biểu tượng dùng chung
Phương thức Symbol.for()
cố gắng tra cứu mọi ký hiệu hiện có trong
sổ đăng ký biểu tượng chung trên toàn thời gian chạy với một chuỗi nhất định làm khoá và trả về
ký hiệu khớp nếu tìm thấy một mã. Nếu không tìm thấy biểu tượng, Chrome sẽ tạo một biểu tượng
bằng khoá được chỉ định và thêm khoá đó vào sổ đăng ký chung:
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
Các khoá này không trùng lặp chức năng với nội dung mô tả được chỉ định cho
Dữ liệu gốc Symbol
do tác giả tạo. Để truy cập một biểu tượng trong sổ đăng ký biểu tượng,
trước tiên, bạn phải tạo tệp bằng for()
:
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol().for( "String" );
> false
Symbol().for( "String" ) === Symbol().for( "String" );
> true
Để truy xuất khoá của bất kỳ biểu tượng nào trong sổ đăng ký biểu tượng, hãy sử dụng
Symbol.keyFor()
:
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
"Phổ biến" ký hiệu
Ký hiệu phổ biến là các thuộc tính tĩnh của đối tượng Symbol
, mỗi thuộc tính
chính là một biểu tượng. Những ký hiệu nổi tiếng cung cấp khoá thuộc tính duy nhất cho
truy cập và sửa đổi các phương thức tích hợp của JavaScript, đồng thời ngăn chặn
để tránh bị ghi đè vô tình.
Symbol;
> function Symbol()
asyncIterator: Symbol(Symbol.asyncIterator)
for: function for()
hasInstance: Symbol("Symbol.hasInstance")
isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
iterator: Symbol(Symbol.iterator)
keyFor: function keyFor()
length: 0
match: Symbol("Symbol.match")
matchAll: Symbol("Symbol.matchAll")
name: "Symbol"
prototype: Object { … }
replace: Symbol("Symbol.replace")
search: Symbol("Symbol.search")
species: Symbol("Symbol.species")
split: Symbol("Symbol.split")
toPrimitive: Symbol("Symbol.toPrimitive")
toStringTag: Symbol("Symbol.toStringTag")
unscopables: Symbol("Symbol.unscopables")
<prototype>: function ()
Vì ký hiệu là một tính năng đặc trưng của ES6, nên các giá trị tượng trưng này nhằm mục đích sử dụng làm "điểm mở rộng" dành cho nhà phát triển sửa đổi đoạn mã mà không gây ra vấn đề về khả năng tương thích ngược.
Các giá trị biểu tượng nổi tiếng thường được cách điệu bằng
Tiền tố @@
hoặc được gói trong %
để
phân biệt khoá của chúng với nguyên mẫu có thể biến đổi. Ví dụ: @@match
(hoặc %match%
) là tham chiếu đến Symbol.match
bất biến, chứ không phải
String.prototype.match
.
Kiểm tra kiến thức
Bạn có thể sử dụng new
để tạo biểu tượng không?
Câu nào sau đây mô tả biểu tượng "nổi tiếng"?