ES6 Symbol 数据类型

ES6引入了Symbol数据类型,解决对象属性名冲突问题。Symbol是原始类型,不可变且每个值独一无二。它不能与其他类型隐式转换,但可显式转为字符串。常用于对象属性名,避免属性覆盖。Symbol属性不参与for...in、Object.keys等遍历,也无法通过常规方式访问,需用obj[Symbol.key]。Symbol.create、Symbol.keyFor分别用于创建新的Symbol值和查找已登记的Symbol。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ES6-Symbol 类型


  1. ES5 除类数组对象(类数组对象名可以为数字,对象必须有 length 属性,可以用数组下标的方式访问对象属性,但不能通过点的方式访问)外,对象属性名都是字符串,这很容易造成属性名的冲突。而且 JavaScript 是弱类型语言,属性名冲突不会报错,处于代码执行顺序后面的属性值会覆盖前面的属性值(属性值容易被篡改),这样对象的属性就不能保证是我们想要的。

  2. ES6 引入了Symbol数据类型很好地解决了对象属性名冲突的问题。

  3. Symbol表示 独一无二的值 ,它是原始数据类型,不能用 new

  4. ES6之后JavaScript就有了7种数据类型,分别是:NumberStringBooleannullundefinedObjectSymbol

基本用法


Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示控制台或者作为字符串的时候使用,便于区分。

let name = Symbol('name');
console.log(name); // Symbol(name);
console.log(typeof name); // "symbol"
特点
  1. Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象;

  2. Symbol 表示独一无二的值,因此带有相同参数的两个 Symbol 值也不相等;

// 没有参数的情况
let name1 = Symbol();
let name2 = Symbol();

name1 === name2 // false

// 有参数的情况
let name1 = Symbol('foo');
let name2 = Symbol('foo');

name1 === name2 // false
  1. Symbol 不能进行隐式类型转换
let name = Symbol('foo');
console.log('你好,' + name);
// 报错:Cannot convert a Symbol value to a string(无法将symbol值转换为字符串)

console.log(`你好,${name}`);
// 报错:Cannot convert a Symbol value to a string(无法将symbol值转换为字符串)

console.log(name + 1);
// 报错:Cannot convert a Symbol value to a number(无法将symbol值转换为数值)
  1. Symbol 值可以显式转为字符串
let name = Symbol('foo');
console.log(String(name)); // "Symbol(foo)"
console.log(name.toString); // "Symbol(foo)"
  1. Symbol 值不能转化为数字
let name = Symbol('foo');
console.log(Number.name);
// 报错:Cannot convert a Symbol value to a number(无法将symbol值转换为数值)
  1. Symbol 值可以转换为布尔值
let name = Symbol('foo');
console.log(Boolean(name)); // true
console.log(!name); // false

Symbol 应用场景


  1. 作为对象属性名

Symbol 声明的对象名不能用 key.value 的形式获取对象的属性值,要用 [ ],原因:
1. ES5中对象 .(点) 运算符获取的属性名是字符串, 用 key.value 的形式会将属性名识别为字符串,新建一个属性名给对象,无法和 Symbol 属性区别
2. 方括号中带双引号的属性名表示字符串属性,不带双引号的属性名表示 Symbol 属性,一次区别二者

let sy = Symbol();

// 写法 1
let syObject = {};
syObject[sy] = 'symbol';
console.log(syObject); // {Symbol(): "symbol"}

// 写法 2
let syObject = {
    [sy]: "symbol"
};
console.log(syObject); // {Symbol(): "symbol"}

// 写法 3
let syObject = {};
Object.defineProperty(syObject, sy, {value: "symbol"});
console.log(syObject); // {Symbol(): "symbol"}

// 万万不能用点
syObject[sy]; // "symbol";
syObject.sy; // 'undefined'
// 因为 syObject.sy === syObject["sy"]
  1. Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for...infor...of 的循环中,也不会被 Object.keys()Object.getOwnPropertyNames() 返回。如果要读取一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols()Reflect.ownKeys() 取到。
let sy = Symbol();
let syObject = {};
syObject[sy] = "symbol";
console.log(syObject); // {Symbol(): "symbol"}

for (let i in syObject) {
    console.log(i); // 无输出
}

Object.keys(syObject); // []
Object.getOwnpropertyNames(syObject); // []
Object.getOwnpropertySymbols(syObject); // [Symbol()]
Reflect.ownKeys(syObject); // [Symbol()]

Symbol的方法

  1. Symbol.for()

作用:用于将描述相同的 Symbol 变量指向同一个 Symbol

let a1 = Symbol.for('a');let a2 = Symbol.for('a');a1 === a2 // truetypeof a1 // "symbol"typeof a2 // "symbol"let a3 = Symbol('a');a1 === a3 // false
  • Symbol()Symbol.for() 的相同点:
    1. 它们定义的值类型都为 “Symbol”;
  • Symbol()Symbol.for() 的不同点:
    1. Symbol() 定义的值每次都是新建,即使描述相同值也不相等;
    2. Symbol() 定义的值会先检查给定的描述是否已经存在,如果不存在才会新建一个值,并把这个值登记在全局环境中供搜索,Symbol.for() 定义相同描述的值时会被搜索到,描述相同则他们就是一个值。
  1. Symbol.keyFor()

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

let a1 = Symbol.for('a');
Symbol.keyFor(a1); // "a"
let a2 = Symbol('a');
Symbol.keyFor(a2); // undefined// a1已经用Symbol.for()登记过,因此返回的key为"a",而a2没有被登记,因此返回undefined

Symbol的属性

  1. Symbol.prototype.descirption

description用于返回 Symbol 数据的描述

// Symbol() 定义的数据
let a = Symbol('acc');
console.log(a.description); // "acc"
Symbol.keyFor(a); // undefined

// Symbol.for() 定义的数据
let a1 = Symbol.for('acc');
console.log(a1.description); // "acc"
Symbol.keyFor(a1); // "acc"

// 未指定描述的数据
let a2 = Symbol.();
console.log(a1.description); // undefined

description属性和Symbol.keyFor()方法的区别是:description 能返回所有 Symbol 数据类型的描述,而 Symbol.keyFor() 只能返回 Symbol.for() 在全局注册过的描述。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iteval

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值