Hướng dẫn sử dụng ECMAScript Symbol
Xem thêm các chuyên mục:
Nhóm thành viên của o7planning đã xây dựng một website tuyệt vời và miễn phí giúp mọi người học tiếng Anh, học từ vựng dễ dàng hơn. Hãy truy cập để học tiếng Anh ngay bây giờ:
-
1- Khái niệm về Symbol
-
Symbol là một "kiểu dữ liệu nguyên thủy" (Primitive data type) mới, được giới thiệu trong ECMAScript 6. Trước ES6 chúng ta chỉ có 5 kiểu nguyên thủy là Number, String, Boolean, null, undefined.
-
-
Để tạo ra một Symbol bạn sử dụng cú pháp dưới đây:
-
// Create a Symbol var mySymbol1 = Symbol(); // Create a Symbol var mySymbol2 = Symbol("Something");
-
Chú ý rằng: Symbol không phải là một lớp, vì vậy bạn không thể tạo nó bằng toán tử new:
-
var mySymbol1 = new Simbol(); // ==> ERROR!! var mySymbol2 = new Simbol("Something"); // ==> ERROR!!
-
Tất cả các kiểu nguyên thủy Number, String, Boolean, null, undefined đều rất rõ ràng và tường minh.
-
- Number: 1, 2, 3, ...
- String: "Hello", "Bye", ...
- Boolean: true, false
- null
- undefined
-
Symbol là một thứ trừu tượng, bạn không thể sờ vào được nó, và không thể biết giá trị thực tế của nó là gì. Symbol là hoàn toàn duy nhất (Hoàn toàn khác nhau), điều đó có nghĩa là nếu bạn tạo ra 2 Symbol, thì chúng là khác nhau, kể cả khi bạn tạo ra 2 Symbol theo cùng một cách.
-
symbol-example1.js
var symbolA1 = Symbol(); var symbolA2 = Symbol(); console.log(symbolA1); // Symbol() console.log(symbolA2); // Symbol() console.log(symbolA1 === symbolA2); // false var symbolB1 = Symbol("Tom"); var symbolB2 = Symbol("Tom"); console.log(symbolB1); // Symbol(Tom) console.log(symbolB2); // Symbol(Tom) console.log(symbolB1 === symbolB2); // false
-
-
-
2- Symbol - Key
-
Symbol có thể sử dụng như một khóa (Key) cho các đối tượng Map.
-
symbol-map-key-example.js
var key1 = Symbol(); var key2 = Symbol(); var key3 = Symbol("Something"); var map = new Map(); map.set(key1, "Tom"); map.set("a_string_key", "Donald"); map.set(key2, "Jerry"); map.set(key3, "Mickey"); console.log( map.get(key1)); // Tom console.log( map.get("a_string_key")); // Donald console.log( map.get(key2)); // Jerry console.log( map.get(key3)); // Mickey
-
-
[Symbol]?
-
Symbol có thể được sử dụng như một property của một đối tượng.
-
symbol-object-property-example.js
var prop1 = Symbol(); var prop2 = Symbol(); var prop3 = Symbol("Something"); var myObject = { name : "Tom", gender: "Male", [prop1]: "Something 1", [prop2]: "Something 2", [prop3]: "Something 3", }; console.log( myObject["name"] ); // Tom console.log( myObject["gender"] ); // Male console.log( myObject[prop1] ); // Something 1
-
-
Symbol thực sự có ích để bạn định nghĩa metadata (Siêu dữ liệu) trong một đối tượng. Nếu property (của một đối tượng) là một Symbol, nó sẽ không được nhận biết bởi các hàm trả về các property.
-
symbol-metadata-example.js
const sym = Symbol() const foo = { name: 'Tom', age: 25, [sym]: 'Some Hidden Metadata' } let keys = Object.keys(foo) // name, age console.log("keys: " + keys); let propNames = Object.getOwnPropertyNames(foo) // name, age console.log("propNames: " + propNames); for(let val of keys) { console.log(foo[val]) // Tom // 25 }
-
-
Các Symbol Property không hoàn toàn ẩn, bạn vẫn có thể lấy ra danh sách các Symbol Property của một đối tượng thông qua các phương thức sau:
-
Object.getOwnPropertySymbols(someObject); Reflect.ownKeys(someObject);
-
Ví dụ:
-
symbol-get-props-example.js
const sym1 = Symbol(); const sym2 = Symbol("Test"); const someObject = { name: 'Tom', age: 25, [sym1]: 'Some Hidden Metadata 1', [sym2]: 'Some Hidden Metadata 2' } var symbolProps = Object.getOwnPropertySymbols(someObject); console.log(symbolProps); // [ Symbol(), Symbol(Test) ] var objKeys = Reflect.ownKeys(someObject); console.log(objKeys); // [ 'name', 'age', Symbol(), Symbol(Test) ]
-
3- Symbol - Enums
-
Trong ES5 rất thường xuyên bạn phải tạo ra các hằng số (constants) để đại diện cho khái niệm nào đó. Và kiểu dữ liệu thường được sử dụng để định nghĩa hằng số là Number hoặc String.
-
OK, Chẳng hạn bạn cần tạo ra 4 hằng số đại diện cho 4 mùa của năm, và hàm getWeather(season) trả về thời tiết tương ứng với mùa được truyền vào.
-
var SEASON_SPRING = "SPRING"; var SEASON_SUMMER = "SUMMER"; var SEASON_AUTUMN = "AUTUMN"; var SEASON_WINTER = "WINTER"; function getWeather(season) { switch(season) { case SEASON_SPRING: return "warm"; case SEASON_SUMMER: return "hot"; case SEASON_AUTUMN: return "cool"; case SEASON_WINTER: return "cold"; default: throw 'Invalid season'; } } console.log( getWeather(SEASON_SPRING) ); // warm
-
Đôi khi bạn sử dụng sai hằng số trong code nhưng vẫn được chương trình chấp nhận. Điều này thật nguy hiểm.
-
var SEASON_SPRING = "SPRING"; var SEASON_SUMMER = "SUMMER"; var SEASON_AUTUMN = "AUTUMN"; var SEASON_WINTER = "WINTER"; var FRAMEWORK_SPRING = "SPRING"; var FRAMEWORK_STRUTS = "STRUTS"; var weather1 = getWeather( SEASON_SPRING ); // warm // (***) var weather2 = getWeather( FRAMEWORK_SPRING ); // warm
-
Sử dụng Symbol để định nghĩa các hằng số là một giải pháp tốt cho bạn trong trường hợp này. Các hằng số kiểu Symbol đại diện cho một khái niệm cụ thể nào đó được gọi là các Enums (Giống với khái niệm Enums trong Java).
-
symbol-enums-example.js
// Season Enums: const SEASON_SPRING = Symbol(); const SEASON_SUMMER = Symbol(); const SEASON_AUTUMN = Symbol(); const SEASON_WINTER = Symbol(); // Framework Enums: const FRAMEWORK_SPRING = Symbol(); const FRAMEWORK_STRUTS = Symbol(); function getWeather(season) { // Season Enums switch(season) { case SEASON_SPRING: return "warm"; case SEASON_SUMMER: return "hot"; case SEASON_AUTUMN: return "cool"; case SEASON_WINTER: return "cold"; default: throw 'Invalid season'; } } console.log( getWeather(SEASON_SPRING) ); // warm console.log( getWeather(FRAMEWORK_SPRING) ); // Throw Error: Invalid season
-
4- Symbol.for(key) & Symbol.forKey(symbol)
-
Phương thức Symbol.for(keyName) trả về một giá trị là một Symbol tương ứng với khóa keyName trong một đối tượng Map toàn cục (Global). Nếu khóa keyName không tồn tại trong đối tượng Map toàn cục, một cặp keyName/Symbol(keyName) sẽ được thêm vào đối tượng Map, và trả về Symbol(keyName) nói trên.
-
-
symbol-for-example.js
const tom = Symbol.for('Tom') // If the Symbol does not exist, it's created const tom2 = Symbol.for('Tom') // The Symbol exists, so it is returned console.log( tom === tom2); // true
-
Symbol.for() & Symbol.for(undefined) là giống nhau.
-
symbol-for-example2.js
const foo = Symbol.for(); const bar = Symbol.for(undefined); console.log( foo === bar); // true
-
Nếu một Symbol đang được quản lý trên đối tượng Map toàn cục, bạn có thể tìm được khóa của nó bằng cách sử dụng phương thức Symbol.keyFor(symbol).
-
symbol-keyFor-example.js
const foo = Symbol.for('someKey');// This Symbol in Global Map. const key1 = Symbol.keyFor(foo); // someKey console.log(key1); // someKey const bar = Symbol("Test");// This Symbol not in Global Map. const key2 = Symbol.keyFor(bar); console.log(key2); // undefined