Bài đăng này là về Symbol()
, được cung cấp với các ví dụ thực tế tôi có thể tìm / tạo và các sự kiện & định nghĩa tôi có thể tìm thấy.
TLDR;
Đây Symbol()
là kiểu dữ liệu, được giới thiệu cùng với việc phát hành ECMAScript 6 (ES6).
Có hai sự thật gây tò mò về Biểu tượng.
kiểu dữ liệu đầu tiên và kiểu dữ liệu duy nhất trong JavaScript không có nghĩa đen
bất kỳ biến nào, được xác định bằng Symbol()
, đều có nội dung độc đáo, nhưng nó không thực sự riêng tư .
bất kỳ dữ liệu nào cũng có Biểu tượng riêng và đối với cùng một dữ liệu, các Biểu tượng sẽ giống nhau . Thông tin thêm trong đoạn văn sau, nếu không thì đó không phải là TLRD; :)
Làm thế nào để tôi khởi tạo biểu tượng?
1. Để có một mã định danh duy nhất có giá trị gỡ lỗi
Bạn có thể làm theo cách này:
var mySymbol1 = Symbol();
Hoặc theo cách này:
var mySymbol2 = Symbol("some text here");
Các "some text here"
chuỗi không thể được chiết xuất từ các biểu tượng, nó chỉ là một mô tả cho mục đích gỡ lỗi. Nó không thay đổi hành vi của biểu tượng theo bất kỳ cách nào. Mặc dù, bạn có thể làm console.log
điều đó (điều này là công bằng, vì giá trị là để gỡ lỗi, để không nhầm lẫn nhật ký đó với một số mục nhật ký khác):
console.log(mySymbol2);
// Symbol(some text here)
2. Để có được một biểu tượng cho một số dữ liệu chuỗi
Trong trường hợp này, giá trị của biểu tượng thực sự được tính đến và theo cách này, hai biểu tượng có thể không phải là duy nhất.
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
Chúng ta hãy gọi những biểu tượng đó là "biểu tượng loại hai". Chúng không giao nhau với các ký hiệu "loại thứ nhất" (nghĩa là các ký hiệu được xác định bằng Symbol(data)
) theo bất kỳ cách nào.
Hai đoạn tiếp theo chỉ liên quan đến biểu tượng loại đầu tiên .
Làm cách nào để tôi hưởng lợi từ việc sử dụng Biểu tượng thay vì các loại dữ liệu cũ hơn?
Trước tiên chúng ta hãy xem xét một đối tượng, một kiểu dữ liệu tiêu chuẩn. Chúng ta có thể định nghĩa một số cặp khóa-giá trị ở đó và có quyền truy cập vào các giá trị bằng cách chỉ định khóa.
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
Nếu chúng ta có hai người với tên Peter thì sao?
Làm điều này:
var persons = {"peter":"first", "peter":"pan"};
sẽ không có ý nghĩa nhiều.
Vì vậy, dường như là một vấn đề của hai người hoàn toàn khác nhau có cùng tên. Sau đó hãy tham khảo mới Symbol()
. Nó giống như một người trong cuộc sống thực - bất kỳ người nào cũng là duy nhất , nhưng tên của họ có thể bằng nhau. Hãy xác định hai "người".
var a = Symbol("peter");
var b = Symbol("peter");
Bây giờ chúng tôi đã có hai người khác nhau có cùng tên. Là người của chúng ta thực sự khác nhau? Họ đang; bạn có thể kiểm tra điều này:
console.log(a == b);
// false
Làm thế nào để chúng ta có lợi ở đó?
Chúng tôi có thể tạo hai mục trong đối tượng của bạn cho những người khác nhau và họ không thể bị nhầm lẫn theo bất kỳ cách nào.
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
Lưu ý:
Tuy nhiên, đáng chú ý là việc xâu chuỗi đối tượng JSON.stringify
sẽ bỏ tất cả các cặp được khởi tạo với Biểu tượng làm khóa.
Thực hiện Object.keys
sẽ không trả lại các Symbol()->value
cặp như vậy .
Sử dụng khởi tạo này, hoàn toàn không thể nhầm lẫn các mục nhập cho người thứ nhất và người thứ hai. Gọi console.log
cho họ sẽ xuất chính xác tên thứ hai của họ.
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
Khi được sử dụng trong đối tượng, nó khác như thế nào so với việc xác định thuộc tính không thể đếm được?
Thật vậy, đã có một cách để xác định một tài sản được ẩn Object.keys
và liệt kê. Đây là:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Điều gì khác biệt Symbol()
mang lại ở đó? Sự khác biệt là bạn vẫn có thể nhận được thuộc tính được xác định Object.defineProperty
theo cách thông thường:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
Và nếu được định nghĩa bằng Biểu tượng như trong đoạn trước:
fruit = Symbol("apple");
Bạn sẽ có khả năng nhận giá trị của nó chỉ khi biết biến của nó, tức là
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
Hơn nữa, việc xác định một thuộc tính khác dưới khóa "apple"
sẽ làm cho đối tượng bỏ đi thuộc tính cũ hơn (và nếu được mã hóa cứng, nó có thể gây ra lỗi). Vì vậy, không còn táo! Thật tiếc. Nhắc đến đoạn trước, các Biểu tượng là duy nhất và xác định một khóa Symbol()
sẽ làm cho nó trở nên duy nhất.
Loại chuyển đổi và kiểm tra
Không giống như các loại dữ liệu khác, không thể chuyển đổi Symbol()
sang bất kỳ loại dữ liệu nào khác.
Có thể "tạo" một biểu tượng dựa trên kiểu dữ liệu nguyên thủy bằng cách gọi Symbol(data)
.
Về mặt kiểm tra loại, không có gì thay đổi.
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false