Hướng dẫn và ví dụ JavaScript Symbol
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
Các hướng dẫn ECMAScript, Javascript
- Giới thiệu về Javascript và ECMAScript
- Bắt đầu nhanh với Javascript
- Hộp thoại Alert, Confirm, Prompt trong Javascript
- Bắt đầu nhanh với JavaScript
- Biến (Variable) trong JavaScript
- Các toán tử Bitwise
- Mảng (Array) trong JavaScript
- Vòng lặp trong JavaScript
- Hàm trong JavaScript
- Hướng dẫn và ví dụ JavaScript Number
- Hướng dẫn và ví dụ JavaScript Boolean
- Hướng dẫn và ví dụ JavaScript String
- Câu lệnh rẽ nhánh if/else trong JavaScript
- Câu lệnh rẽ nhánh switch trong JavaScript
- Hướng dẫn xử lý lỗi trong JavaScript
- Hướng dẫn và ví dụ JavaScript Date
- Hướng dẫn và ví dụ JavaScript Module
- Lịch sử phát triển của module trong JavaScript
- Hàm setTimeout và setInterval trong JavaScript
- Hướng dẫn và ví dụ Javascript Form Validation
- Hướng dẫn và ví dụ JavaScript Web Cookie
- Từ khóa void trong JavaScript
- Lớp và đối tượng trong JavaScript
- Kỹ thuật mô phỏng lớp và kế thừa trong JavaScript
- Thừa kế và đa hình trong JavaScript
- Tìm hiểu về Duck Typing trong JavaScript
- Hướng dẫn và ví dụ JavaScript Symbol
- Hướng dẫn JavaScript Set Collection
- Hướng dẫn JavaScript Map Collection
- Tìm hiểu về JavaScript Iterable và Iterator
- Hướng dẫn sử dụng biểu thức chính quy trong JavaScript
- Hướng dẫn và ví dụ JavaScript Promise, Async Await
- Hướng dẫn và ví dụ Javascript Window
- Hướng dẫn và ví dụ Javascript Console
- Hướng dẫn và ví dụ Javascript Screen
- Hướng dẫn và ví dụ Javascript Navigator
- Hướng dẫn và ví dụ Javascript Geolocation API
- Hướng dẫn và ví dụ Javascript Location
- Hướng dẫn và ví dụ Javascript History API
- Hướng dẫn và ví dụ Javascript Statusbar
- Hướng dẫn và ví dụ Javascript Locationbar
- Hướng dẫn và ví dụ Javascript Scrollbars
- Hướng dẫn và ví dụ Javascript Menubar
- Hướng dẫn xử lý JSON trong JavaScript
- Xử lý sự kiện (Event) trong Javascript
- Hướng dẫn và ví dụ Javascript MouseEvent
- Hướng dẫn và ví dụ Javascript WheelEvent
- Hướng dẫn và ví dụ Javascript KeyboardEvent
- Hướng dẫn và ví dụ Javascript FocusEvent
- Hướng dẫn và ví dụ Javascript InputEvent
- Hướng dẫn và ví dụ Javascript ChangeEvent
- Hướng dẫn và ví dụ Javascript DragEvent
- Hướng dẫn và ví dụ Javascript HashChangeEvent
- Hướng dẫn và ví dụ Javascript URL Encoding
- Hướng dẫn và ví dụ Javascript FileReader
- Hướng dẫn và ví dụ Javascript XMLHttpRequest
- Hướng dẫn và ví dụ Javascript Fetch API
- Phân tích XML trong Javascript với DOMParser
- Giới thiệu về Javascript HTML5 Canvas API
- Làm nổi bật Code với thư viện Javascript SyntaxHighlighter
- Polyfill là gì trong khoa học lập trình?
Show More