对JS数据类型symbol的一些介绍

前言

今天重新看vue3文档的时候发现了一个之前遗漏的地方,就是在依赖注入那里,提到了大型项目中使用symbol来避免参数的重名冲突,当时最开始看的时候就想搜搜什么是symbol数据类型来着,结果忘了,这一忘就是一年多,今天抓到了,可千万得写个文章记录一下。

JavaScript中的Symbol数据类型

1. 什么是Symbol

在JavaScript中,Symbol是一种基本数据类型(primitive data type)。Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。

2. Symbol如何使用

你可以这样创建一个Symbol实例:

js 复制代码
let s1 = Symbol();

由于每个Symbol值都是唯一的,因此它们通常用作对象属性的键(key),以确保在不同的对象中不会发生键名冲突。这就解决了属性命名冲突的问题。

当你创建一个Symbol变量时,可以选择传递一个参数。这个参数是一个字符串,用于描述Symbol的用途。这个描述字符串主要用于程序调试时的跟踪,并不影响Symbol本身的唯一性。例如:

js 复制代码
let sym = Symbol("my symbol");
console.log(sym.toString()); // "Symbol(my symbol)"

在这个例子中,"my symbol"就是传递给Symbol()函数的描述字符串。当我们调用sym.toString()时,它会返回一个包含这个描述的字符串。但是需要注意的是,即使两个Symbol的描述字符串相同,它们也是不相等的

js 复制代码
let sym1 = Symbol("my symbol");
let sym2 = Symbol("my symbol");
console.log(sym1 === sym2); // false

在这个例子中,尽管sym1sym2的描述字符串都是"my symbol",但它们代表的是两个不同的、唯一的Symbol值。

3. Symbol应用场景以及简单实例

创建迭代器方法

可以使用Symbol来创建迭代器方法。以下是一个示例:

js 复制代码
const myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
console.log([...myIterable]); // [1, 2, 3]

在这个例子中,我们定义了一个对象myIterable,并给它添加了一个Symbol.iterator属性。这个属性是一个生成器函数,它返回一个迭代器,这个迭代器可以生成1、2和3。

创建私有属性

可以使用Symbol来创建私有属性。以下是一个示例:

js 复制代码
const _private = Symbol('private');
class MyClass {
    constructor() {
        this[_private] = 'private value';
    }
    getPrivateValue() {
        return this[_private];
    }
}
const instance = new MyClass();
console.log(instance.getPrivateValue()); // 'private value'
console.log(instance._private); // undefined

在这个例子中,我们定义了一个类MyClass,并给它添加了一个私有属性_private。这个属性只能通过类的方法(如getPrivateValue)访问,不能直接通过实例访问。

需要注意的是,虽然使用Symbol可以模拟私有属性,但这并不是真正的私有性,因为仍然可以通过Object.getOwnPropertySymbols()来获取到所有的Symbol属性。在JavaScript中,真正的私有属性可以通过在属性名前加上井号(#)来创建,或者你干脆用TS的private标识符就完了。

4. symbol注意事项

  1. 新的数据类型Symbol是ES6引入的新的数据类型。
  2. 特殊的用途Symbol主要用于创建唯一的对象属性键。在许多常见的编程场景中,使用字符串作为属性键已经足够了。只有在你需要确保属性键不会与其他键冲突时,才需要使用Symbol
  3. 访问限制 :使用Symbol作为属性键时,不能使用点符号(.)来访问属性,只能使用方括号(\[\])。
  4. 序列化问题Symbol值不能被直接序列化为字符串。如果你需要将对象转换为JSON格式,那么Symbol属性将会被完全忽略。这可能会导致一些意想不到的结果,特别是当你试图调试或检查对象状态时。
相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端