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入门

相关推荐
中微子3 分钟前
JavaScript 事件机制:捕获、冒泡与事件委托详解
前端·javascript
蓝翔认证10级掘手30 分钟前
🤯 家人们谁懂啊!我的摸鱼脚本它...它成精了!🚀
javascript
前端康师傅1 小时前
JavaScript 中你不知道的按位运算
前端·javascript
tianchang1 小时前
策略模式(Strategy Pattern)深入解析与实战应用
前端·javascript·代码规范
best6661 小时前
JavaScript的Math内置对象,到底是何方神圣?
javascript
掘金安东尼1 小时前
技术解析:高级 Excel 财务报表解析器的架构与实现
前端·javascript·面试
每天开心1 小时前
一文教你掌握事件机制
前端·javascript·ai编程
LeeAt2 小时前
真的!真的就一句话就能明白this指向问题
前端·javascript
Winwin2 小时前
js基础-数据类型
javascript
Winwin2 小时前
哈?Boolean能作为回调函数?
javascript