JavaScript类型之Symbol

Symbol 是 ECMAScript 6 (ES6) 引入的一种新的原始数据类型,它是 JavaScript 的第七种数据类型(前六种是:Undefined、Null、Boolean、String、Number 和 Object)。

基本概念

创建 Symbol

javascript

javascript 复制代码
// 创建一个 Symbol
let sym1 = Symbol();
let sym2 = Symbol('description'); // 可选的描述字符串

console.log(typeof sym1); // "symbol"
console.log(sym2.toString()); // "Symbol(description)"

特性

  1. 唯一性 :每个 Symbol 都是唯一的,即使描述相同 javascript

    ini 复制代码
    let sym1 = Symbol('foo');
    let sym2 = Symbol('foo');
    
    console.log(sym1 === sym2); // false
  2. 不可枚举性 :Symbol 属性默认不会出现在 for...inObject.keys() 等枚举中

  3. 不可强制转换 :不能隐式转换为字符串或数字 javascript

    javascript 复制代码
    let sym = Symbol();
    console.log("Symbol: " + sym); // TypeError
    console.log(Number(sym)); // TypeError

主要用途

1. 作为对象属性键

javascript

ini 复制代码
const MY_KEY = Symbol();
let obj = {};

obj[MY_KEY] = 'secret value';
console.log(obj[MY_KEY]); // "secret value"

// 或者使用计算属性名
let obj2 = {
  [MY_KEY]: 'another secret'
};

2. 定义类的私有成员

javascript

kotlin 复制代码
const _counter = Symbol('counter');
const _action = Symbol('action');

class Countdown {
  constructor(counter, action) {
    this[_counter] = counter;
    this[_action] = action;
  }
  
  dec() {
    if (this[_counter] < 1) return;
    this[_counter]--;
    if (this[_counter] === 0) {
      this[_action]();
    }
  }
}

3. 避免属性名冲突

javascript

ini 复制代码
// 不同库可以安全地添加属性到对象上
const LIB1_PROP = Symbol('lib1 property');
const LIB2_PROP = Symbol('lib2 property');

let obj = {};
obj[LIB1_PROP] = 'Library 1 data';
obj[LIB2_PROP] = 'Library 2 data';

全局 Symbol 注册表

Symbol.for()

在全局 Symbol 注册表中创建或获取 Symbol:

javascript

ini 复制代码
let sym1 = Symbol.for('shared');
let sym2 = Symbol.for('shared');

console.log(sym1 === sym2); // true

Symbol.keyFor()

获取全局 Symbol 的键:

javascript

javascript 复制代码
let sym = Symbol.for('foo');
console.log(Symbol.keyFor(sym)); // "foo"

内置 Symbol

ES6 定义了一些内置的 Symbol 值,称为"知名 Symbol",用于实现特定的语言行为:

  • Symbol.iterator:定义对象的默认迭代器
  • Symbol.toStringTag:自定义对象的 toString() 行为
  • Symbol.hasInstance:自定义 instanceof 操作符的行为
  • Symbol.species:指定创建派生对象的构造函数
  • Symbol.toPrimitive:将对象转换为原始值的方法
  • Symbol.isConcatSpreadable:配置对象作为 Array.prototype.concat() 的参数时是否展开其元素

示例:实现可迭代对象

javascript

javascript 复制代码
const myIterable = {
  [Symbol.iterator]: function* () {
    yield 1;
    yield 2;
    yield 3;
  }
};

for (let value of myIterable) {
  console.log(value); // 1, 2, 3
}

注意事项

  1. Symbol 不能使用 new 操作符(不是构造函数)
  2. Symbol 值不能与其他类型的值进行运算
  3. Symbol 作为属性名时,必须使用方括号语法(不能使用点操作符)
  4. 使用 Object.getOwnPropertySymbols() 可以获取对象的所有 Symbol 属性

Symbol 提供了一种创建唯一标识符的机制,非常适合用于需要避免命名冲突的场景,特别是在大型项目和库的开发中。

相关推荐
星之金币1 分钟前
关于我用Cursor优化了一篇文章:30 分钟学会定制属于你的编程语言
前端·javascript
每天都想着怎么摸鱼的前端菜鸟3 分钟前
【uniapp】uni.chooseImage在Android 13以下机型第一次调用授权后无权限问题
javascript·uni-app
市民中心的蟋蟀4 分钟前
第十一章 这三个全局状态管理库之间的共性与差异 【上】
前端·javascript·react.js
小宋10214 分钟前
el-table的select回显问题
javascript·vue.js·elementui
豆豆(设计前端)24 分钟前
在 JavaScript 中,你可以使用 Date 对象来获取 当前日期 和 当前时间、当前年份。
开发语言·javascript·ecmascript
DoraBigHead35 分钟前
深入 JavaScript 作用域机制:透视 V8 引擎背后的执行秘密
前端·javascript
薛定谔的算法37 分钟前
JavaScript闭包深度解析:从基础概念到柯里化实践
javascript
菥菥爱嘻嘻40 分钟前
React---Hooks深入
前端·javascript·react.js
只与明月听43 分钟前
前端学算法-二叉树(一)
前端·javascript·算法
谢尔登1 小时前
【React】使用 useContext + useReducer 实现一个轻量的状态管理库
前端·javascript·react.js