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

相关推荐
伍哥的传说6 小时前
CSS+JavaScript 禁用浏览器复制功能的几种方法
前端·javascript·css·vue.js·vue·css3·禁用浏览器复制
lichenyang4537 小时前
Axios封装以及添加拦截器
前端·javascript·react.js·typescript
Trust yourself2437 小时前
在easyui中如何设置自带的弹窗,有输入框
前端·javascript·easyui
Feather_749 小时前
从Taro的Dialog.open出发,学习远程控制组件之【事件驱动】
javascript·学习·taro
\光辉岁月/9 小时前
Axios基本使用
javascript·axios
波波鱼દ ᵕ̈ ૩10 小时前
学习:JS[6]环境对象+回调函数+事件流+事件委托+其他事件+元素尺寸位置
前端·javascript·学习
cypking10 小时前
解决electron+vue-router在history模式下打包后首页空白问题
javascript·vue.js·electron
Watermelo61710 小时前
极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图
前端·javascript·vue.js·数据挖掘·数据分析·流程图·数据可视化
Micro麦可乐10 小时前
前端拖拽排序实现详解:从原理到实践 - 附完整代码
前端·javascript·html5·拖拽排序·drop api·拖拽api
Watermelo61710 小时前
Web Worker:让前端飞起来的隐形引擎
前端·javascript·vue.js·数据挖掘·数据分析·node.js·es6