js基石之Symbol值

js基石之数据类型一:类型分类&区别
js基石之数据类型二:类型判断
js基石之数据类型三:类型转换
js基石之Number:本质
js基石之Number:应用(数字运算,数字&字符串转换,不同进制表示&相互转换)
js基石之字符: ASCII,GBK,Unicode,utf-32,utf-16,utf-8,encodeuri,encodeuricomponent,base64
js基石之Symbol值

先有问题再有答案

  1. Symbol是什么
  2. Symbol和其他数据类型有什么关系?
  3. Symbol有什么特性
  4. 有哪些应用场景
  5. 你都掌握了哪些有用的Symbol值?

Symbol是什么

symbol是一种基本数据类型, 通过Symbol函数生成symbol值,symbol值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的

一个原始值

javascript 复制代码
const s = Symbol('a')
typeof s // 'symbol'

Symbol函数

Symbol作为函数的唯一作用就是生成symbol值。

Symbol对象

  • 对象属性:Symbol.iterator,Symbol.toPrimitive,Symbol.toStringTag...
  • 原型方法:Symbol.prototype原型定义了toString,valueOf方法 同时Symbol原型链上也有Function.prototype&Object.prototype。
  • 静态方法:Symbol.for,Symbol.keyFor

Symbol&其他类型

Number: 不能相互转换

javascript 复制代码
let sym = Symbol('1'); 

let num = sym + 1; // Uncaught TypeError: Cannot convert a Symbol value to a number

Number(sym) // Uncaught TypeError: Cannot convert a Symbol value to a number

parseInt(sym) // Uncaught TypeError: Cannot convert a Symbol value to a number

String:不能隐式转换

ini 复制代码
let sym = Symbol('test'); 
let str = sym + 'hello'; // Cannot convert a Symbol value to a string

可以显式转换

ini 复制代码
let sym = Symbol('test'); 

let str1 = sym.toString(); // 使用 Symbol.prototype.toString 方法进行转换 
// 返回:"Symbol(test)" 

let str2 = String(sym); // 使用 String 函数进行转换  
// 返回:"Symbol(test)"

Boolean

所有的 Symbol 类型的值在转换为布尔值时都是 true,无论它们的描述是什么

ini 复制代码
let sym1 = Symbol('test'); 
let bool1 = !!sym1; // 返回:true 

let sym2 = Symbol(); 
let bool2 = !!sym2; // 返回:true

let bool = Boolean(sym2); // 返回:true

包装类

Symbol函数不能通过new调用,没有对应的包装类 es2015之后新增的基本数据类型(BigInt)都不能通过new调用,这是JavaScript 语言的设计决定。

虽然引擎提供了自动装箱和拆箱功能,但是Symbol&BigInt两种类型 不适合当做对象使用。

Symbol的特性

1:symbol没有字面量形式 只能通过Symbol函数生成。

ini 复制代码
let sym1 = Symbol('test'); 

2:symbol表示唯一值

每个 Symbol 值都是唯一的,即使你创建了两个具有相同描述的 Symbol 值,它们也是不相等的。这使得 Symbol 值成为了创建对象的唯一属性键的理想选择,可以避免属性名的冲突。

ini 复制代码
let sym1 = Symbol('test'); 
let sym2 = Symbol('test'); 
sym1 === sym2 // false

3:不可枚举

Symbol 值作为对象的属性键时,这个属性不会出现在常规的遍历操作中(如 for...in 循环、Object.keys()、JSON.stringify() 等),只能通过 Object.getOwnPropertySymbols() 或 Reflect.ownKeys() 来获取。

ini 复制代码
let sym = Symbol('test'); 
let obj = { [sym]: 'value', prop: 'value' }; 
console.log(Object.keys(obj)); // 输出:['prop'] console.log(Object.getOwnPropertySymbols(obj)); // 输出:[Symbol(test)]

应用场景

创建唯一的属性键:

由于每个 Symbol 都是唯一的,所以可以用它来创建唯一的属性键,避免属性名的冲突。

ini 复制代码
let id = Symbol('id'); 
let user = { 
   [id]: 1, 
   name: 'John', 
   age: 30 
};

内置的Symbol值(常用的)

Symbol.iterator:迭代器

javascript 复制代码
let iterable = {
  [Symbol.iterator]() {
    let i = 0;
    return {
      next() {
        if (i < 5) {
          return { value: i++, done: false };
        } else {
          return { value: undefined, done: true };
        }
      }
    };
  }
};

for (let value of iterable) {
  console.log(value); // 输出:0, 1, 2, 3, 4
}

Symbol.toPrimitive:类型转换

csharp 复制代码
const obj = {
    value: 1,
    [Symbol.toPrimitive](){
        return 10
    },
};

obj + 1 // 11
obj + '1' // '101'
'1' + obj // 110

Symbol.toStringTag:类型判断

javascript 复制代码
Number.prototype[Symbol.toStringTag] = 'String';
let a = 12;
Object.prototype.toString.call(a)  // '[object String]'成功的将数字改变为字符串

补充

symbol具有唯一性。还有哪些方式可以表示唯一性?

  1. 时间戳
ini 复制代码
let timestamp = Date.now();
  1. 使用 Math.random():
    Math.random() 函数返回一个介于 0(包含)和 1(不包含)之间的随机数,所以你可以用它来生成一个几乎唯一的值。但是,Math.random() 函数的结果是不可预测的,所以它不能保证生成的值一定是唯一的。
vbscript 复制代码
Math.random().toString(36).substring(2)
  1. uuid
javascript 复制代码
npm install uuid
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

参考

  1. es6_symbol
  2. mdn_Symbol
相关推荐
吠品12 分钟前
DicomViewer24 的 CI 又红了:MPR 测试偶发失败排查记
java·服务器·前端
troy12827 分钟前
用 Cube.js 构建金融财务系统的 Semantic Layer:从架构到实战
javascript·金融·架构
泡海椒3 小时前
JQuick-Excel FORMAT 导出格式实战:日期、金额显示与 TRANSFORM 的边界
前端·python·excel
唠点键盘之外的8 小时前
15 微调 vs RAG:到底怎么选
人工智能·机器学习·面试·aigc
迅猛龙办公室9 小时前
Python输出当前计算机的系统日期和时间
开发语言·前端·python
小狼154549 小时前
浏览器扩展脚本为什么有时候不生效:注入时机、iframe 和单页路由,多多开票助手
前端·chrome
じòぴé南冸じょうげん10 小时前
油猴脚本突然发现变成灰色了,无法使用?页面不生效?刷新页面没反应?
前端
怕浪猫10 小时前
Prompt Engineering 面试怎么考?这 5 个范式你必须会
面试·程序员·github
Csvn11 小时前
组合式 API(Composition API)
前端
是翎12 小时前
AI开发工程师面试指南
人工智能·面试·职场和发展