这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战javascript
ES5 的对象属性名都是字符串,容易形成属性名的冲突java
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值git
Symbol 是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)github
console.log(typeof Symbol());
// symbol
复制代码
使用 Symbol() 产生惟一值缓存
// 不可以使用 new 命令
const a = Symbol();
const b = Symbol();
console.log(a === b);
// false
复制代码
Symbol 类型不能够添加属性markdown
const a = Symbol();
a.name = 'a';
console.log(a.name);
// undefined
复制代码
Symbol 函数可添加描述,相同描述返回值并不相同函数
const a = Symbol('a');
console.log(a.toString());
// Symbol(a)
复制代码
Symbol 不能与其余值混合运算,但能够显式转换为字符串、布尔值oop
当咱们须要重复使用一个 Symbol 值,能够使用 Symbol.for 进行全局登记post
const a = Symbol.for("123");
const b = Symbol.for("123");
console.log(a === b);
// true
复制代码
Sybmol.keyFor 能够返回一个已登记的 Symbol 的 Keyui
const a = Symbol.for("123");
console.log(Symbol.keyFor(a));
// 123
复制代码
Symbol 做为属性名解决名称冲突
// 做为属性名时,须使用 [] 进行声明和取值
const name = Symbol.for("name");
const person = {
[name]: 'Cade'
}
console.log(person[name]);
// cade
复制代码
缓存操做中解决名称冲突问题
class Cache {
static data = {};
static set(name, value) {
this.data[name] = value;
}
static get(name) {
return this.data[name];
}
}
let user = {
name: 'Cade',
key: Symbol('user')
};
let cart = {
name: '购物车',
key: Symbol('cart')
};
Cache.set(user.key, user);
Cache.set(cart.key, cart);
console.log(Cache.get(user.key));
复制代码
Symbol 做为属性名不能被遍历获得
不能经过 for in、Object.keys 获取 Symbol 类型属性名
let symbol = Symbol("123");
let obj = {
name: "Cade",
[symbol]: "abc"
};
for (const key in obj) {
console.log(key);
}
// name
for (const key of Object.keys(obj)) {
console.log(key);
}
// name
复制代码
能够使用 Object.getOwnPropertySymbols 获取全部 Symbol 属性
for (const key of Object.getOwnPropertySymbols(obj)) {
console.log(key);
}
复制代码
也能够使用 Reflect.ownKeys(obj) 获取全部属性包括 Symbol
for (const key of Reflect.ownKeys(obj)) {
console.log(key);
}
复制代码
JavaScript 内置了许多系统 Symbol,以使用它们来微调对象的各个方面
Symbol.hasInstance
使用 a instanceof A 时,实际上执行的是 A[Symbol.hasInstance](a)
class A {
static [Symbol.hasInstance](val) {
return val instanceof Array;
}
}
console.log([1, 2, 3] instanceof A);
// true
复制代码
Symbol.toPrimitive
当对象被转为原始类型的值时,会调用 Symbol.toPrimitive 方法,返回该对象对应的原始类型值
Symbol.toPrimitive 被调用时,会接受一个字符串参数,表示当前运算的模式,一共有三种模式
const obj = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 123;
case 'string':
return 'str';
case 'default':
return 'default';
default:
throw new Error();
}
}
};
console.log(2 * obj);
// 246
console.log(3 + obj);
// '3default'
console.log(obj == 'default');
// true
console.log(String(obj));
// 'str'
复制代码
其余内置 Symbol 参见 Well-Known Symbols