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

相关推荐
翻滚吧键盘38 分钟前
js代码09
开发语言·javascript·ecmascript
Amy.Wang2 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景2 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼2 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
百锦再2 小时前
Vue中对象赋值问题:对象引用被保留,仅部分属性被覆盖
前端·javascript·vue.js·vue·web·reactive·ref
jingling5552 小时前
面试版-前端开发核心知识
开发语言·前端·javascript·vue.js·面试·前端框架
FogLetter2 小时前
图片懒加载:让网页飞起来的魔法技巧 ✨
前端·javascript·css
拾光拾趣录2 小时前
JavaScript 加载对浏览器渲染的影响
前端·javascript·浏览器
浪裡遊4 小时前
Sass详解:功能特性、常用方法与最佳实践
开发语言·前端·javascript·css·vue.js·rust·sass
夏梦春蝉5 小时前
ES6从入门到精通:常用知识点
前端·javascript·es6