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

相关推荐
Van_captain20 小时前
rn_for_openharmony常用组件_Divider分割线
javascript·开源·harmonyos
Yanni4Night21 小时前
Parcel 作者:如何用静态Hermes把JavaScript编译成C语言
前端·javascript·rust
遇见~未来21 小时前
JavaScript构造函数与Class终极指南
开发语言·javascript·原型模式
毕设源码-邱学长1 天前
【开题答辩全过程】以 基于VUE的打车系统的设计与实现为例,包含答辩的问题和答案
前端·javascript·vue.js
用户39051332192881 天前
JS判断空值只知道“||”?不如来试试这个操作符
前端·javascript
wuk9981 天前
梁非线性动力学方程MATLAB编程实现
前端·javascript·matlab
XiaoYu20021 天前
第11章 LangChain
前端·javascript·langchain
yyf198905251 天前
Vue 框架相关中文文献
前端·javascript·vue.js
行者961 天前
Flutter适配OpenHarmony:国际化i18n实现中的常见陷阱与解决方案
开发语言·javascript·flutter·harmonyos·鸿蒙
我的写法有点潮1 天前
推荐几个国外比较流行的UI库(上)
前端·javascript·css