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
相关推荐
web130933203982 分钟前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_23422 分钟前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
测试老哥30 分钟前
外包干了两年,技术退步明显。。。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
如若1231 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~2 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语2 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport2 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg2 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww2 小时前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest
m0_748254882 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui