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

相关推荐
低保和光头哪个先来7 分钟前
CSS+JS实现单例老虎机切换图片动画
前端·javascript·css
坐公交也用券10 分钟前
适用于vue3+pnpm项目自动化类型检查及构建的Python脚本
开发语言·javascript·python·typescript·自动化
小小鸟00822 分钟前
Vue响应式原理
前端·javascript·vue.js
前端老曹27 分钟前
vue3 三级路由无法缓存的终终终终终终极解决方案
前端·javascript·vue.js
零Suger27 分钟前
React Router v7数据模式使用指南
javascript·笔记·react.js
Mr.Jessy6 小时前
JavaScript高级:构造函数与原型
开发语言·前端·javascript·学习·ecmascript
爱上妖精的尾巴8 小时前
6-4 WPS JS宏 不重复随机取值应用
开发语言·前端·javascript
三七吃山漆10 小时前
攻防世界——wife_wife
前端·javascript·web安全·网络安全·ctf
用户479492835691510 小时前
面试官问"try-catch影响性能吗",我用数据打脸
前端·javascript·面试
GISer_Jing10 小时前
前端营销技术实战:数据+AI实战指南
前端·javascript·人工智能