【ES6】Symbol数据类型

简介: 【ES6】Symbol数据类型

数字化管理平台

Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus

权限系统案例

个人博客地址

ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名,这样就从根本上防止属性名的冲突。

Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。基本上可以说,它是一种类似于字符串的数据类型。

Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"

上面代码中,s1和s2是两个 Symbol 值。如果不加参数,它们在控制台的输出都是Symbol(),不利于区分。有了参数以后,就等于为它们加上了描述,输出的时候就能够分清,到底是哪一个值。

ES2019 提供了一个实例属性description,直接返回 Symbol 的描述。

const sym = Symbol('foo');
sym.description // "foo"

由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

let mySymbol = Symbol("foo");
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
  [mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"

注意,Symbol 值作为对象属性名时,不能用点运算符

const mySymbol = Symbol();
const a = {};
a.mySymbol = 'Hello!';//这里mySymbol作为a的属性进行赋值
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"

上面代码中,因为点运算符后面总是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个 Symbol 值。同理,在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。

Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。

let syObject = {};
syObject[sy] = "kk";
console.log(syObject);
for (let i in syObject) {
  console.log(i);
}    // 无输出
Object.keys(syObject);                     // []
Object.getOwnPropertySymbols(syObject);    // [Symbol(key1)]
Reflect.ownKeys(syObject);                 // [Symbol(key1)]

Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。

Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值,如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索。

let yellow = Symbol("Yellow");
let yellow1 = Symbol.for("Yellow");
yellow === yellow1;      // false
let yellow2 = Symbol.for("Yellow");
yellow1 === yellow2;     // true

Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值。

Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。

let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined

上面代码中,变量s2属于未登记的 Symbol 值,所以返回undefined。

注意,Symbol.for()为 Symbol 值登记的名字,是全局环境的,不管有没有在全局环境运行。

image.png

Symbol数据相关应用

相关文章
|
1天前
|
JavaScript 前端开发
ES6:什么是Symbol?
ES6:什么是Symbol?
21 1
|
1天前
ES6之Symbol
ES6之Symbol
|
1天前
|
JavaScript 前端开发 开发者
编程笔记 html5&css&js 071 JavaScript Symbol 数据类型
编程笔记 html5&css&js 071 JavaScript Symbol 数据类型
|
1天前
|
JavaScript 前端开发
|
1天前
|
JavaScript 前端开发 开发者
|
1天前
|
存储 JavaScript
ES6+新特性-Symbol与Set/Map数据结构
ES6 引入了三种新的数据结构:Symbol、Set和Map。Symbol是唯一且不可变的值,常用于定义对象的独特属性;Set存储不重复值,适合数组去重;Map则是键值对集合,键可为任意类型,提供了更灵活的存储方式。这些新数据结构提供了更高效的操作手段,分别解决了属性命名冲突、数据去重和复杂键值对存储的问题。示例展示了如何使用Symbol、Set和Map进行基本操作。
|
1天前
|
JavaScript
js开发:请解释什么是ES6的Symbol,以及它的用途。
ES6的Symbol数据类型创建唯一值,常用于对象属性键(防冲突)和私有属性。示例展示了如何创建及使用Symbol:即使描述相同,两个Symbol也不等;作为对象属性如`obj[symbol1] = 'value1'`;也可作枚举值,如`Color.RED = Symbol('red')`。
|
1天前
|
JavaScript 前端开发
ES6之原始数据类型Symbol
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。Symbol的作用是创建一个不可变且唯一的标识符,可以用作对象属性的键。它可以用来解决属性名冲突的问题,避免命名冲突。
37 0
|
8月前
ES6: Symbol概念与用法举例
ES6: Symbol概念与用法举例
28 0