ES6 Symbol如何方便你接手离职同事的代码

如何接手离职同事的代码,ES6 Symbol,你值得了解

一.简单介绍一下 Symbol 类型

  1. 首先它是一种基本类型,像 string,bigInt 这些数据类型,没有方法,也不能 new,声明方法 const s1 = Symbol("desc")和其他基本类型相似 。
  2. 其次它的返回值是唯一且不可变的原始值,猜测在 V8 引擎中原理可能是由一个自增 symbol 链表或哈希实现。

二.代码实际中理解

一是用于做对象的键名,使得键名独一无二,这就是我为啥说 symbol 有利于接手离职同事的代码。

ini 复制代码
​
​
//现在我需要添加一下新的成员变量age存储age信息,你也不知道原来有木有这个变量。
const age = Symbol("age");
//这样声明的age变量一定不会覆盖本来成员变量
user[age] = 18;
// 我们可以在不影响原来数据结构下新增成员变量通过obj[age]访问
console.log(user.name, user[ID], user[age]);
​
csharp 复制代码
const user = {
  name: "Alice",
  [ID]: 123, //[]的意思是取值
  /*
  ·
  ·很多成员变量,而且变量名抽象
  ·
  ·
  */
};

假如这个对象成员很多,我想加一个age,但是懒得看原来的代码,可能因为原来的代码根本不知道变量的含义,前同事命名方式太抽象。

我们可以这样做

ini 复制代码
//现在我需要添加一下新的成员变量age存储age信息,你也不知道原来有木有这个变量。
const age = Symbol("age");
user[age] = 18;
// 我们可以在不影响原来数据结构下新增成员变量通过obj[age]访问

你可能会想到你的离职同事之前也和你一样写方式的,你不就炸了吗?

不用担心,并不会,其实这样添加的age变量一定不会覆盖本来成员变量。

它的返回值通过js机制和v8引擎的某种实现有关,前面也提了可能就是用递增链表或者哈希实现的。

javascript 复制代码
console.log( Symbol("age") === Symbol("age")) //  输出 false 
console.log( Symbol() === Symbol() ) //  可以不传description参数 一样 输出 false 

哎,这时候可能会有疑问,那我就要创建可复用的Symbol,怎么弄呢?

用Symbol.for('key')方法就行了,代码如下:

ini 复制代码
const s1 = Symbol.for('shared');
const s2 = Symbol.for('shared');
console.log(s1 === s2); // 这个时候就是true啦,不过感觉没啥用

另外Symbol 作为对象的键时不可枚举,可以避免外部直接修改状态。

补充一点Symbol 作为对象的键时不可枚举是什么意思呢?

就是说在用for,Obj.key()方式遍历时,用Symbol 作为对象的键不能被访问到。

那你会有疑问了,那我就要访问咋办?

用这个方法这个 Object.getOwnPropertySymbols(obj) 方法就可以了

请看代码:

ini 复制代码
​
const user = {
  name: "Alice",
  [ID]: 123, //[]的意思是取值
};
const age = Symbol("age");
user[age] = 18;
for (let i in user) {
  console.log(i); // 输出 name
}
Object.getOwnPropertyNames(user) // [name]
Object.getOwnPropertySymbols(user) // [Symbol(id),Symbol(age)]

有人问看不懂怎么办?我只能说懂得都懂,不懂你问ai就行了,因为作者也不太懂

二是用来做对象的值,实现类型c++中的有的而js没有枚举类型

比如我们来写一个订单订单的状态:

javascript 复制代码
// orderStatus.js
const ORDER_STATUS = {
  PENDING: Symbol("pending"), // 待支付
  PAID: Symbol("paid"), // 已支付
  SHIPPED: Symbol("shipped"), // 已发货
  COMPLETED: Symbol("completed"), // 已完成
  CANCELLED: Symbol("cancelled"), // 已取消
};
module.exports = ORDER_STATUS;

然后再来写订单的状态变化:

javascript 复制代码
​
// orderService.js
const STATUS = require("./orderStatus");
​
function updateOrderStatus(currentStatus, newStatus) {
  // 安全校验:确保新状态是有效的 Symbol 值
  if (!Object.values(STATUS).includes(newStatus)) {
    throw new Error("Invalid order status 无效的订单状态");
  }
​
  // 仅允许合法的状态转换(示例逻辑)
  if (currentStatus === STATUS.PAID && newStatus !== STATUS.SHIPPED) {
    throw new Error(
      "Paid order must transition to shipped  已付订单必须过渡到已付订单"
    );
  }
​
  // 更新状态...
  console.log(
    `Order status updated to:订单状态更新为: ${newStatus.description}`
  );
}
// 调用示例
updateOrderStatus(STATUS.PENDING, STATUS.PAID); // 合法操作
updateOrderStatus(STATUS.PAID, "invalid_status"); // 抛出异常(字符串无法通过校验)
​

这样可以防止字符串误写影响,像这样:updateStatus("paied")写错 。

三、总结

Symbol是一个es6的基本数据类型,为中大型项目而生,其实有关它的用法还很丰富,特别是访问方法那一块。这里推荐es6大佬阮一峰的讲解Symbol - ECMAScript 6入门

相关推荐
南玖i1 分钟前
vue3 通过 Vue3DraggableResizable实现拖拽弹窗,可修改大小
前端·javascript·vue.js
YAY_tyy7 分钟前
Three.js 开发实战教程(五):外部 3D 模型加载与优化实战
前端·javascript·3d·three.js
Zuckjet_3 小时前
开启 3D 之旅 - 你的第一个 WebGL 三角形
前端·javascript·3d·webgl
bitbitDown5 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
YAY_tyy5 小时前
【JavaScript 性能优化实战】第六篇:性能监控与自动化优化
javascript·性能优化·自动化
gnip6 小时前
实现AI对话光标跟随效果
前端·javascript
闭着眼睛学算法7 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
烛阴7 小时前
【TS 设计模式完全指南】构建你的专属“通知中心”:深入观察者模式
javascript·设计模式·typescript
lumi.7 小时前
Vue.js 从入门到实践1:环境搭建、数据绑定与条件渲染
前端·javascript·vue.js
二十雨辰7 小时前
vue核心原理实现
前端·javascript·vue.js