Symbol 数据类型

Symbol是ES6引入的一种新的基本数据类型,用于创建独一无二的值,常用于对象属性的标识符以避免命名冲突。Symbol值是唯一的,不可进行运算,也不能通过for...in循环遍历,但可以使用Reflect.ownKeys获取对象的所有键名。Symbol可以通过Symbol.for()创建并登记在全球环境中,便于在不同环境中找到相同的值。此外,JavaScript还提供了一些内置的Symbol值,如Symbol.iterator等。

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

Symbol 数据类型
Symbol概述 symbol 是ES6 引入了一种新的基本数据类型(原始数据类型) Symbol ,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是: undefined 、 null 、布尔值(Boolean)、字符串 (String)、数值(Number)、对象(Object)。
每个从 Symbol() 返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据 类型仅有的目的
Symbol数据类型的特点
1、Symbol的值是唯一的,用来解决命名冲突的问题
2、Symbol值不能与其他数据类型进行运算
3、Symbol定义得的对象的属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象 的所有键名
Symbol语法与描述
Symbol([description])
description 可选 可选的,字符串类型。对symbol的描述,可用于调试但不是访问symbol本身。
直接使用 Symbol() 创建新的symbol类型,并用一个可选的字符串作为其描述
let sym1 = Symbol(); let sym2 = Symbol(‘foo’); let sym3 = Symbol(‘foo’);
上面的代码创建了三个新的symbol类型。 注意, Symbol(“foo”) 不会强制将字符串 “foo” 转换成 symbol类型。它每次都会创建一个新的 symbol类型:
Symbol(“foo”) === Symbol(“foo”); // false
sym2===sym3;//false
下面带有 new 运算符的语法将抛出 TypeError 错误
var sym = new Symbol(); // TypeError
这会阻止创建一个显式的 Symbol 包装器对象而不是一个 Symbol 值。围绕原始数据类型创建一个显式 包装器对象从 ECMAScript 6 开始不再被支持。 然而,现有的原始包装器对象,如 new Boolean 、 new String 以及 new Number ,因为遗留原因仍可被创建。
如果你真的想创建一个 Symbol 包装器对象 ( Symbol wrapper object ),你可以使用 Object() 函 数:
var sym = Symbol(“foo”);
typeof sym; // “symbol”
var symObj = Object(sym);
typeof symObj; // “object”
Symbol创建对象的属性
//Symbol定义得的对象的属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象 的所有键名
let age = Symbol(“age”);
let sex = Symbol(“sex”);
let person = { name: ‘zhangsan’, [age]: 23, [sex]: ‘male’, [Symbol(‘test’)]: ‘test’ }
for (const key in person) {
//name zhangsan
console.log(key, person[key]);//name 属性 }
//使用Reflect.ownKeys来获取对象的所有键名
//[‘name’, Symbol(age), Symbol(sex), Symbol(test)]
let keys = Reflect.ownKeys(person)
//取出所有的值
keys.forEach(element => { console.log(person[element]) });
Symbol创建对象的属性
let game = {
name: ‘俄罗斯方块’,
up() { console.log(‘game中的向上移动’) },
down() { console.log(‘game中的向下移动’) }
}
//声明一个对象
let methods = { up: Symbol(‘up’), down: Symbol(‘down’) }
//给game中添加一个up方法
game[methods.up] = function () { console.log(“后添加的up方法”) }
//给game中添加一个down方法
game[methods.down] = function () { console.log(“后添加的down方法”) }
//up方法的调用
game.up() gamemethods.up;
Symbol.for() 有时,我们希望重新使用同一个 Symbol 值, Symbol.for() 方法可以做到这一点。它接受一个字符串 作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就 新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
let s1 = Symbol.for(‘foo’);
let s2 = Symbol.for(‘foo’);
s1 === s2 // true
上面代码中, s1 和 s2 都是 Symbol 值,但是它们都是由同样参数的 Symbol.for 方法生成的,所以实 际上是同一个值
Symbol.for() 与 Symbol() 这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局 环境中供搜索,后者不会。 Symbol.for() 不会每次调用就返回一个新的 Symbol 类型的值,而是会先 检查给定的 key 是否已经存在,如果不存在才会新建一个值。比如,如果你调用 Symbol.for(“cat”) 30 次,每次都会返回同一个 Symbol 值,但是调用 Symbol(“cat”) 30 次,会返 回 30 个不同的 Symbol 值
Symbol.for(“bar”) === Symbol.for(“bar”) // true
Symbol(“bar”) === Symbol(“bar”) // false
上面代码中,由于 Symbol() 写法没有登记机制,所以每次调用都会返回一个不同的值。 Symbol.keyFor() 方法返回一个已登记的 Symbol 类型值的 key 。
let s1 = Symbol.for(“foo”);
Symbol.keyFor(s1) // “foo”
let s2 = Symbol(“foo”);
Symbol.keyFor(s2) // undefined
上面代码中,变量 s2 属于未登记的 Symbol 值,所以返回 undefined 。 注意, Symbol.for() 为 Symbol 值登记的名字,是全局环境的,不管有没有在全局环境运行。
function foo() {
return Symbol.for(‘bar’);
}
const x = foo();
const y = Symbol.for(‘bar’);
console.log(x === y); // true
上面代码中, Symbol.for(‘bar’) 是函数内部运行的,但是生成的 Symbol 值是登记在全局环境的。 所以,第二次运行 Symbol.for(‘bar’) 可以取到这个 Symbol 值。
Symbol.for() 的这个全局登记特性,可以用在不同的 iframe 或 service worker 中取到同一个值。
iframe = document.createElement(‘iframe’);
iframe.src = String(window.location);
document.body.appendChild(iframe);
iframe.contentWindow.Symbol.for(‘foo’) === Symbol.for(‘foo’) // true
上面代码中,iframe 窗口生成的 Symbol 值,可以在主页面得到。
内置的Symbol值 除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。
Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.species Symbol.match
Symbol.replace
Symbol.search
Symbol.split
Symbol.iterator ==>对象的 Symbol.iterator 属性,指向该对象的默认遍历器方法
Symbol.toPrimitive
Symbol.toStringTag
Symbol.unscopables

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值