这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
Symbol:保证每一个属性名都是独一无二的,从根本上防止属性名的冲突。
symbol表示独一无二的值,是JavaScript的第七种数据类型。
// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();
s1 === s2 // false
// 有参数的情况
let s1 = Symbol('cxxd');
let s2 = Symbol('cxxd');
s1 === s2 // false
Symbol值通过Symbol()函数生成,使用typeof,结果为symbol
let a = Symbol();
console.log(typeof a); // "symbol"
注意Symbol()函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。
symbol 还有另一个重要的用途,它们可以用作对象中的键,如下:
const obj = {};
const sym = Symbol();
obj[sym] = "foo";
obj.bar = "bar";
console.log(obj); // { bar: 'bar' }
console.log(sym in obj); // true
console.log(obj[sym]); // foo
console.log(Object.keys(obj)); // ['bar']
这看起来就像可以使用 Symbol 在对象上创建私有属性,但Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。Symbol不会出现在 for...in 、 for...of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
let syObject = {};
syObject[sy] = "kk";
console.log(syObject);
for (let i in syObject) {
console.log(i);
} // 无输出
Object.keys(syObject); // []
Object.getOwnPropertySymbols(syObject); // [Symbol(key1)] Reflect.ownKeys(syObject); // [Symbol(key1)]
Symbol为 JavaScript 对象提供私有属性还有点困难,但 Symbol 还有别外一个好处,就是避免当不同的库向对象添加属性存在命名冲突的风险。
考虑这样一种情况:两个不同的库想要向一个对象添加基本数据,可能它们都想在对象上设置某种标识符。通过简单地使用 id 作为键,这样存在一个巨大的风险,就是多个库将使用相同的键。
function lib1tag(obj) {
obj.id = 2;
}
function lib2tag(obj) {
obj.id = 3;
}
通过使用 Symbol,每个库可以在实例化时生成所需的 Symbol。然后用生成 Symbol 的值做为对象的属性:
const library1property = Symbol("lib1");
function lib1tag(obj) {
obj[library1property] = 2;
}
const library2property = Symbol("lib2");
function lib2tag(obj) {
obj[library2property] = 3;
}
以上就是为什么要用Symbol 类型的一些整合。