一.Symbol
Symbol是JavaScript的新的一種基本數據類型,表示獨一無二的值.
undefined,null,String,Number,Boolean,Object,Symbol
引入的原因是防止對象的屬性或者方法被無意的覆蓋
Symbol的聲明
// 方式1,每次聲明的都是獨一無二的,沒有登記機制
let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
// 方式2,每次聲明的都是登記爲全局範圍,重複聲明會返回已經聲明的Symbol,沒有則創建之
let s1 = Symbol.for('foo');
Symbol.keyFor(someSymbol);返回一個已經登記的Symbol的key
let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
二.Symbol作爲屬性名
- Symbol 值作爲對象屬性名時,不能用點運算符
- 使用 Symbol 值定義屬性時,Symbol 值必須放在方括號之中
let mySymbol = Symbol();
// 第一種寫法
let a = {};
a[mySymbol] = 'Hello!';
// 第二種寫法
let a = {
[mySymbol]: 'Hello!'
};
// 第三種寫法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上寫法都得到同樣結果
a[mySymbol] // "Hello!"
遍歷屬性名
在沒有使用Symbol的情況下可以使用for…in , for…of , Object.keys() , Object.getOwnPropertyNames()方法
但是,使用了Symbol作爲屬性名,Object.getOwnPropertySymbols(obj)獲取對象中使用Symbol作爲屬性名的數組
const obj = {};
let a = Symbol('a');
let b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
const objectSymbols = Object.getOwnPropertySymbols(obj);
objectSymbols
// [Symbol(a), Symbol(b)]
Reflect.ownKeys返回對象的所有屬性名,所有
三.內置Symbol值
http://es6.ruanyifeng.com/#docs/symbol#%E5%86%85%E7%BD%AE%E7%9A%84-Symbol-%E5%80%BC
四.Symbol的用處
1.消除魔術字符串
魔術字符串指的是,在代碼之中多次出現、與代碼形成強耦合的某一個具體的字符串或者數值。
function getArea(shape, options) {
let area = 0;
switch (shape) {
case 'Triangle': // 魔術字符串
area = .5 * options.width * options.height;
break;
/* ... more code ... */
}
return area;
}
getArea('Triangle', { width: 100, height: 100 }); // Triangle魔術字符串
解決
const shapeType = {
triangle: Symbol()
};
function getArea(shape, options) {
let area = 0;
switch (shape) {
case shapeType.triangle:
area = .5 * options.width * options.height;
break;
}
return area;
}
getArea(shapeType.triangle, { width: 100, height: 100 });