深入理解 JavaScript 中的 Symbol
什么是 Symbol
Symbol 是 ECMAScript 6 引入的一种原始数据类型,表示独一无二的值。它常用于定义对象的唯一属性,避免属性名冲突。Symbol 是不可变的且唯一的,使用 Symbol() 函数生成。
const s1 = Symbol();
const s2 = Symbol();
console.log(s1 === s2); // false
Symbol 的基本使用
Symbol 可用于对象的属性名,每个 Symbol 都是唯一的,不会与其他属性名冲突。
const obj = {};
const s1 = Symbol('description1');
const s2 = Symbol('description2');
obj[s1] = '知识星球';
obj[s2] = '前端职场圈';
console.log(obj[s1]); // '知识星球'
console.log(obj[s2]); // '前端职场圈'
console.log(typeof s1); // symbol
Symbol 的唯一性
尽管可以给 Symbol 传递描述(description),但这个描述仅用于调试,两个描述相同的 Symbol 仍然是不同的。
const s1 = Symbol('前端职场圈');
const s2 = Symbol('前端职场圈');
console.log(s1 === s2); // false
console.log(s1); // Symbol(前端职场圈)
Symbol 注册中心
Symbol 有一个全局的注册中心,可以使用 Symbol.for() 方法注册和查询全局的 Symbol。使用相同描述的 Symbol 将会返回相同的 Symbol 实例。
const s1 = Symbol.for('前端职场圈');
const s2 = Symbol.for('前端职场圈');
console.log(s1 === s2); // true
console.log(s1); // Symbol(前端职场圈)
Symbol.keyFor
Symbol.keyFor() 方法返回一个全局注册的 Symbol 的描述,如果 Symbol 未在全局注册,则返回 undefined。
let s1 = Symbol.for('前端职场圈');
let s2 = Symbol('前端职场圈');
console.log(Symbol.keyFor(s1)); // '前端职场圈'
console.log(Symbol.keyFor(s2)); // undefined
Symbol 的使用场景
- 唯一性
在 ES5 中,对象的属性名都是字符串,如果属性名重复,后者会覆盖前者。而每个从 Symbol() 返回的 Symbol 值都是唯一的,可确保对象每个属性名的唯一性,避免属性名冲突。
const s1 = Symbol('test');
const s2 = Symbol('test');
let obj = {
[s1]: "知识星球:前端职场圈",
[s2]: "公众号:前端面试资源"
};
console.log(obj); // { [Symbol(test)]: '知识星球:前端职场圈', [Symbol(test)]: '公众号:前端面试资源' }
// ES5 的情况下会被覆盖
const s1 = 'test';
const s2 = 'test';
let obj2 = {
[s1]: "知识星球:前端职场圈",
[s2]: "公众号:前端面试资源"
};
console.log(obj2); // { test: '公众号:前端面试资源' }
- 私有属性
Symbol 属性不会出现在 Object.keys() 或 JSON.stringify() 的结果中,但可以通过 Object.getOwnPropertySymbols() 获取。
function getObj() {
const s1 = Symbol('公众号:前端面试资源');
const obj = {};
obj[s1] = '公众号:前端面试资源';
return obj;
}
const obj = getObj();
console.log(Object.keys(obj)); // []
console.log(obj[Symbol('公众号:前端面试资源')]); // undefined
const [symbol] = Object.getOwnPropertySymbols(obj);
console.log(obj[symbol]); // '公众号:前端面试资源'
// JSON.stringify() 会忽略 Symbol 属性
const s1 = Symbol('知识星球: 前端职场圈');
const s2 = Symbol('公众号: 前端面试资源');
const obj2 = {
[s1]: '知识星球: 前端职场圈',
[s2]: '公众号: 前端面试资源',
test1: s1,
test2: s2
};
let res = JSON.stringify(obj2);
console.log(res); // "{}"
总结
Symbol 为 JavaScript 提供了一种独特且安全的方式来定义对象属性,避免属性名冲突和确保属性的唯一性。了解和掌握 Symbol 的使用,对于编写更健壮和可维护的代码非常有帮助。在面试中展示对 Symbol 的理解和应用场景,能够显著提升你的技术水平和竞争力。