阅读视图

发现新文章,点击刷新页面。

从0-1封装一个React组件

第一步:初始化与安装依赖 创建一个空文件夹并初始化: 接下来安装依赖。对于组件库,核心原则是: react 和 react-dom 应该是 Peer Dependencies(宿主环境提供),而不是打

🌹🌹🌹bro,AntD 6.0.0 来了

写前端写久了,我们对 UI 组件升级这事似乎再熟悉不过—— 但只要一升级大版本,你就会发现: 它像在考试,你像在裸奔。 AntD 6.0.0 发布之后, 我一边看更新日志,一边感觉官方在说: 这篇文章

浏览器渲染原理

在日常面试中,我们经常会遇到这样一个问题: “在浏览器输入 URL 后,页面是如何展现出来的?” 这个看似简单的问题,其实背后涉及浏览器渲染、网络请求、解析执行等一系列复杂流程。本文将聚焦于 浏览器渲

JavaScript 中的 Symbol:特性与实战应用

JavaScript 中的 Symbol:特性与实战应用

在 JavaScript 的世界里,数据类型是构建一切的基础。ES6 的出现为我们带来了两种新的简单数据类型,其中之一就是 Symbol。本文将结合实例,详细解析 Symbol 的特性、用法及实际价值。

一、Symbol 是什么?数据类型的新成员

JavaScript 共有 8 种数据类型,可分为 "简单数据类型" 和 "复杂数据类型" 两大类:

  • 复杂数据类型:仅object一种

  • 简单数据类型:

    • 传统类型:numberbooleanstringnullundefined
    • ES6 新增:bigint(大数)、symbol(符号)

Symbol 的核心定义是:一种独一无二的值,它的出现主要是为了解决对象属性名冲突的问题。

二、Symbol 的声明方式

Symbol 通过Symbol()函数声明(注意:虽然使用函数形式,但它是简单数据类型,而非对象),语法如下:

// 基本声明
const sym = Symbol();
// 带描述符的声明(描述符仅用于标识,不影响唯一性)
const symWithDesc = Symbol('这是一个描述');

代码示例解析(symbol/1.js)

// 声明两个Symbol类型变量
const id1 = Symbol();
console.log(typeof id1); // 输出:"symbol",证明是简单数据类型

const id2 = Symbol();
// 核心特性:独一无二,即使无参数,两个Symbol也不相等
console.log(id1 === id2); // 输出:false

从代码可见,即使两个 Symbol 变量没有任何参数,它们也绝对不相等,这是 Symbol 最核心的特性。

三、Symbol 作为对象的唯一键:解决命名冲突

在多人协作开发中,对象的动态特性可能导致属性名冲突(后定义的属性会覆盖先定义的)。而 Symbol 作为对象的键(key)时,能完美避免这个问题,因为它是独一无二的。

代码示例解析(symbol/2.js)

// 两个描述符相同的Symbol,依然不相等
const s1 = Symbol('二哈');
const s2 = Symbol('二哈');
console.log(s1 === s2); // 输出:false

// 声明一个用于"秘密信息"的Symbol键
const secretKey = Symbol('secret');
console.log(secretKey, '//////'); // 输出:Symbol(secret) //////

// 演示Symbol作为对象键的优势
const a = "ecut";
const user = {
    [secretKey]: '111222', // Symbol作为键,避免被意外覆盖
    email: '123@qq.com',
    name: '曹仁',
    "a": 456, // 字符串键"a"
    [a]: 123  // 变量a(值为"ecut")作为键,等价于"ecut":123
};

// 访问对象属性
console.log(user.ecut, user[a]); // 输出:123 123(两种方式访问同一个键)

// 普通字符串键可以被修改
user.email = 'ren@qq.com';

在上述代码中,secretKey作为 Symbol 键,即使其他开发者在对象中添加同名字符串键,也不会影响它的值,确保了数据的安全性。

四、Symbol 键的不可枚举性与访问方式

与普通字符串键不同,Symbol 作为对象的键时,不会被for...in循环枚举,也不会被Object.keys()等方法获取。这一特性让 Symbol 键适合存储 "私有" 或 "辅助" 信息。

若要访问对象中的 Symbol 键,需使用Object.getOwnPropertySymbols()方法,该方法会返回对象中所有 Symbol 键组成的数组。

代码示例解析

// 声明两个Symbol变量
const wes = Symbol('Wes');
const person = Symbol('Wes');
// console.log(wes === person); // 输出:false(即使描述相同也不相等)

// 定义包含Symbol键的对象
const classRoom = {
    [Symbol('Mark')]: { grade: 50, gender: 'male' },
    [Symbol('oliva')]: { grade: 80, gender: 'female' },
    [Symbol('oliva')]: { grade: 85, gender: 'female' }, // 不会覆盖前一个oliva,因为是不同Symbol
    "dl": ["张三", "李四"] // 普通字符串键
};

// 1. 测试for...in循环:仅能枚举字符串键
for (const person in classRoom) {
    console.log(person, '////'); // 仅输出:dl ////
}

// 2. 获取所有Symbol键
const syms = Object.getOwnPropertySymbols(classRoom);
console.log(syms); // 输出:[Symbol(Mark), Symbol(oliva), Symbol(oliva)]

// 3. 访问Symbol键对应的值
const data = syms.map(sym => classRoom[sym]);
console.log(data); 
// 输出:[
//   { grade: 50, gender: 'male' },
//   { grade: 80, gender: 'female' },
//   { grade: 85, gender: 'female' }
// ]

代码中,classRoom对象包含 3 个 Symbol 键和 1 个字符串键。for...in循环仅能获取到字符串键dl,而Object.getOwnPropertySymbols()则能准确获取所有 Symbol 键,再通过映射即可访问对应的值。

五、总结

Symbol 作为 ES6 新增的简单数据类型,凭借 "独一无二" 和 "不可枚举" 的特性,在实际开发中有着重要作用:

  1. 作为对象键,避免多人协作时的命名冲突
  2. 存储 "私有" 信息,不被常规枚举方法获取
  3. 描述符仅用于标识,不影响其唯一性

掌握 Symbol 的用法,能让我们在处理对象属性时更加灵活、安全,尤其适合大型项目和多人协作场景。

❌