2.3 ES6 Symbol
Category ES6 Tutorial
Overview
ES6 introduces a new primitive data type Symbol, which represents a unique value and is primarily used to define unique property names for objects.
In addition to Number, String, Boolean, Object, null, and undefined, ES6 also adds Symbol to the data types.
Basic Usage
The Symbol function cannot be used with the new command because Symbol is a primitive data type, not an object. It can accept a string as a parameter to provide a description for the newly created Symbol, which is used for display in the console or as a string to facilitate differentiation.
let sy = Symbol("KK");
console.log(sy); // Symbol(KK)
typeof(sy); // "symbol"
// The same parameter Symbol() returns different values
let sy1 = Symbol("kk");
sy === sy1; // false
Usage Scenarios
As a Property Name
Usage
Since each Symbol value is unique, Symbol can be used as a property name for an object to ensure that property names do not conflict.
let sy = Symbol("key1");
// Method 1
let syObject = {};
syObject[sy] = "kk";
console.log(syObject); // {Symbol(key1): "kk"}
// Method 2
let syObject = {
[sy]: "kk"
};
console.log(syObject); // {Symbol(key1): "kk"}
// Method 3
let syObject = {};
Object.defineProperty(syObject, sy, {value: "kk"});
console.log(syObject); // {Symbol(key1): "kk"}
When using Symbol as an object property name, you cannot use the dot operator; you must use square brackets. This is because the dot operator is followed by a string, so the property with the string 'sy' is accessed, not the Symbol value property 'sy'.
let syObject = {};
syObject[sy] = "kk";
syObject[sy]; // "kk"
syObject.sy; // undefined
Points to Note
When a Symbol value is used as a property name, the property is a public property, not a private one, and can be accessed from outside the class. However, it will not appear in for...in or for...of loops, nor will it be returned by Object.keys() or Object.getOwnPropertyNames(). To read the Symbol properties of an object, you can use Object.getOwnPropertySymbols() and Reflect.ownKeys().
let syObject = {};
syObject[sy] = "kk";
console.log(syObject);
for (let i in syObject) {
console.log(i);
} // No output
Object.keys(syObject); // []
Object.getOwnPropertySymbols(syObject); // [Symbol(key1)]
Reflect.ownKeys(syObject); // [Symbol(key1)]
Defining Constants
In ES5, strings are used to represent constants. For example:
const COLOR_RED = "red";
const COLOR_YELLOW = "yellow";
const COLOR_BLUE = "blue";
However, using strings does not guarantee that constants are unique, which can cause some problems:
const COLOR_RED = "red";
const COLOR_YELLOW = "yellow";
const COLOR_BLUE = "blue";
const MY_BLUE = "blue";
function ColorException(message) {
this.message = message;
this.name = "ColorException";
}
function getConstantName(color) {
switch (color) {
case COLOR_RED :
return "COLOR_RED";
case COLOR_YELLOW :
return "COLOR_YELLOW ";
case COLOR_BLUE:
return "COLOR_BLUE";
case MY_BLUE:
return "MY_BLUE";
default:
throw new ColorException("Can't find this color");
}
}
try {
var color = "green"; // green triggers an exception
var colorName = getConstantName(color);
} catch (e) {
var colorName = "unknown";
console.log(e.message, e.name); // Pass the exception object to error handling
}
However, using Symbol to define constants ensures that the values of this set of constants are all unique. Modify the above example using Symbol.
``` const COLOR_RED = Symbol("red"); const COLOR_YELLOW = Symbol("yellow"); const COLOR_BLUE = Symbol("blue");
function ColorException(message) { this.message = message; this.name = "ColorException"; } function getConstantName(color) { switch (color) { case COLOR_RED : return "COLOR_RED"; case COLOR_YELLOW : return "COLOR_YELLOW "; case COLOR