// 3.html
const classRoom = {
[Symbol('Mark')]: {grade: 50, gender: 'male'},
[Symbol('oliva')]: {grade: 80, gender: 'female'},
// 即使标签(描述)和上面一样,这也是一个新的、独立的属性
[Symbol('oliva')]: {grade: 85, gender: 'female'},
"dl": ["张三","李四"]
};
上述代码中,第二个[Symbol('oliva')]并没有覆盖第一个,而是创建了一个全新的属性,完美解决了同名标签可能带来的冲突。
3. 枚举与遍历:Symbol的“隐藏”特性
Symbol属性还有一个重要特性:它们不会被常规的遍历方法枚举到。例如,for...in循环、Object.keys()、Object.values()、Object.entries()以及JSON.stringify()都会“忽略”Symbol属性。
// 3.html
for (const person in classRoom) {
console.log(classRoom[person], '////'); // 只会打印出 "dl" 的值
}
这使得Symbol属性具备了一定的“私有”和“内置”属性特征,不会被轻易暴露出去。
如果你需要获取对象中所有的Symbol属性,必须使用专门的方法:
// 3.html
const syms = Object.getOwnPropertySymbols(classRoom); // 返回一个包含对象自身所有Symbol键的数组
console.log(syms); // 打印出 [Symbol(Mark), Symbol(oliva), Symbol(oliva)]
// 可以结合map方法获取这些属性的值
const data = syms.map(sym => classRoom[sym]);
console.log(data); // 打印出三个学生的对象数组
四、总结
Symbol是ES6为解决JavaScript长期存在的属性命名冲突和元编程问题而引入的一种优雅方案。它:
- 是简单数据类型,独一无二。
- 是创建对象唯一键的理想选择,尤其在多人协作和库的开发中,能有效保证属性安全。
- 具有“半隐藏”特性,不会被常规方法枚举,需用
Object.getOwnPropertySymbols()获取。
掌握了Symbol,你就拥有了在JavaScript对象中创建“命名空间”和“内部插槽”的能力,让你的代码结构更清晰、更健壮。
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。