Symbol的学习笔记-ES6系列5

本文深入探讨ES6中新增的Symbol数据类型,解析其需求背景、基本语法、作为属性的应用及获取方式,对比Symbol.for()与Symbol()的区别。

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

Symbol的学习参考了以下大大们的博客~仅为自己的学习笔记。
http://es6.ruanyifeng.com/#docs/symbol

1. Symbol的需求

在ES5中,对象的属性都是字符串,很容易引起命名冲突的问题。如果你写一个对象,需要有一些属性名你不想别人误操作或修改,则可以借助Symbol来完成。

2. Symbol的基本语法

Symbol为ES6引入的第七种数据类型,也是原始数据类型。表示独一无二的值。

2.1 Symbol()

一个Symbol类型的数据可以用Symbol函数创建,但注意由于不是对象,不能使用new

let s1 = Symbol()
console.log(typeof(s1)) //symbol

Symbol函数可以接收一个字符串作为参数,传入的字符串是对Symbol的描述。方便我们区分。

let s2 = Symbol("s")

由于传入的字符串仅为描述,所以即使传入相同的描述,Symbol创建出来的数据仍然是独一无二的。

let s3 = Symbol("s")
console.log(s2 == s3)  //false
console.log(s2 === s3)  //false

Symbol函数还可以接收一个对象作为参数,但是会先调用对象的toString()方法,并将其返回值作为对Symbol的描述。

let obj = {
	toString:function(){
		return 'cjx'
	}
}
let s4 = Symbol(obj)
console.log(s4) //Symbol(cjx)

在这里插入图片描述

2.2 Symbol.prototype.description

有时如果你想要查看一个symbol数据的描述,可以使用description方法,具体如下

	let obj = {toString:function(){return 'cjx'}}
    let s4 = Symbol(obj)
    console.log(s4.description)  //cjx

在这里插入图片描述

2.3 Symbol作为属性

由于Symbol这独一无二的特性,所以Symbol值我们一般用做对象的属性值。具体的写法如下:

	let name = Symbol("name")
    let age = Symbol("age")
    let gender = Symbol("gender")
    let obj = {
        school:"bupt",
        //第一种写法
        [name]:"cjx"
    }
    //第二种写法
    obj[age] = 18 
    //第三种写法
    Object.defineProperty(obj, gender, { value: 'female' })
    console.log(obj)

在这里插入图片描述
注意:使用Symbol的值做属性的时候,不能使用.属性名来访问,应使用[]来访问。如上例中,如果这样写会取不到

console.log("不应用.访问",obj.name)
console.log("应使用[]访问",obj[name])

在这里插入图片描述

2.4 Symbol属性的获取方式

使用Symbol 值作为属性名时,该属性是公有属性不是私有属性。
但要注意,使用for…in, for…of无法遍历到以Symbol值作为属性名的属性

	console.log("----for in----")
    for(let key in obj){
        console.log(key,obj[key])
    }
    
    console.log("----getOwnPropertySymbols----")
    let SymbolAttr = Object.getOwnPropertySymbols(obj) //返回一个数组
    for(let key of SymbolAttr)
    {
        console.log(key,obj[key])
    }

    console.log("----Reflect.ownKeys----")
    let allAttr = Reflect.ownKeys(obj)
    for(let key of allAttr)
    {
        console.log(key,obj[key])
    }

在这里插入图片描述
从上面我们可以看到,使用for…in方法只能遍历到非Symbol值的属性使用getOwnPropertySymbols只能获取到Symbol值的属性使用Reflect.ownKeys可以获取到所有共有属性

Symbol 作为属性名,该属性不会出现在for…in、for…of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。

2.5 Symbol.for(), Symbol.keyFor()

2.5.1 Symbol.for()

Symbol.for()接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建这样一个Symbol值。

let s1 = Symbol.for('s')
let s2 = Symbol.for('s')
console.log(s1===s2) //true

在这里插入图片描述

这里还引入了一个登记机制的概念。使用Symbol.for创建的会被登记在全局环境中供搜索,而使用Symbol创建的不会被登记。

2.5.2 Symbol.keyFor()

Symbol.keyFor()方法会返回一个已登记的Symbol类型值的key,如:

        let s1 = Symbol("s")
        let s2 = Symbol.for("s")
        console.log("未登记",Symbol.keyFor(s1))
        console.log("登记",Symbol.keyFor(s2))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值