概述
Symbol用来表示独一无二的值, 最大的用法就是用来定义对象的唯一属性名。
基本用法
Symbol函数不能用new新建对象, 因为Symbol是原始数据类型, 不是对象。
Symbol可以接收一个值作为参数, 为新创建的Symbol提供描述, 在控制台输出信息时用来区分。
let sy = Symbol('aaa');
console.log(sy); // Symbol(aaa)
console.log(typeof sy); // "symbol"
// 相同参数的Symbol返回值不同
let sy2 = Symbol('aaa');
console.log(sy2 == sy); // false
使用场景
作为对象的属性名
由于Symbol的值是唯一的, 所以Symbol在作为属性名时, 可以保证属性的唯一。
let sy = Symbol('sy');
// 用法1
let obj = {};
obj[sy] = 'aaa';
console.log(obj); // {Symbol(sy): 'aaa'}
// 用法2,Es6新增语法
let obj2 = {
[sy] : 'aaa'
}
console.log(obj2); // {Symbol(sy): 'aaa'}
Symbol在作为属性名时不能使用.
运算符, 要使用[]
方括号。因为在对象的操作中.
运算符后面代表的是字符串, 所以取到的是字符串sy
的属性值, 而不是作为Symbol值sy
的属性。
let sy = Symbol('sy');
let obj = {};
obj[sy] = 'aaa';
console.log(obj[sy]); // 'aaa'
console.log(obj.sy); // undefined
// .运算符后面代表的是字符串, 所以获取的是对象中字符串'sy'的属性值
obj['sy'] = 'bbb';
console.log(obj.sy); // 'bbb'
console.log(obj); // {sy: 'bbb', Symbol(sy): 'aaa'}
注意点
Symbol值作为属性名是, 该属性是公有属性不是私有属性, 可以在类的外部访问。但是不会出现在for…in循环中, 也不会被Object.keys()获取到。如果要获取一个对象的Symbol值属性, 可以用Object.getOwnPropertySymbols()获取。
let sy = Symbol('sy');
let obj = {};
obj[sy] = 'aaa';
obj['k'] = 'kk';
// for...in 循环用来枚举对象的键
for(let i in obj){
console.log(i);
} // k 输出一个'k', 因为for...in循环不能获取到Symbol值的属性
console.log(Object.keys(obj)); // ['k'] Object.keys()也不能获取到Symbol值
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(sy)] 只用来获取Symbol值的属性
Symbol.for()
Symbol.for()类似于对象的单例模式, 首先会在全局搜索被登记过的Symbol中是否有该字符串作为值的Symbol, 如果有就返回该Symbol值, 如果没有就新建一个并返回该Symbol值, 并且登记在全局环境中以供搜索。
// 用Symbol函数生成的Symbol值不会注册在全局环境中
let sy = Symbol('sy');
let sy2 = Symbol.for('sy');
console.log(sy == sy2); // false
let sy3 = Symbol.for('sy');
console.log(sy2 === sy3); // true
Symbol.keyFor()
Symbol.keyFor()返回一个已登记的Symbol值的key, 用来检测该字符串作为键的Symbol值是否被注册。
// 这种直接写在Symbol函数的参数里的, 不会登记在全局中
let sy = Symbol('sy');
console.log(Symbol.keyFor(sy)); // undefined
let sy2 = Symbol.for('syaaa');
console.log(Symbol.keyFor(sy2)); // 'syaaa'