Symbol

1、概述

ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引入Symbol的原因。

symbol是一种新的数据类型

数据类型

基本类型:Number、String、Boolean、undefined、null

引用类型:Object、Array、Function、Date等等

Symbol的特性就是唯一性

Symbol(符号)是一种新的基本类型值

2、基本使用

let a = Symbol()
let b = Symbol("hello")
console.log(a)
console.log(b)
}

3、Symbol的唯一性

Symbol是代表唯一的意思,同值的Symbol是不相等的

let a = Symbol()
let b = Symbol()
let c = Symbol("hello")
let d = Symbol("hello")
console.log(a == b)//false
console.log(c == d)//false

即使内部传入参数相同也不相等

4、Symbol的内部参数

4.1Symbol内部如果是字符串表示当前这个符合的描述信息

 let b = Symbol("hello")

 

4.2 Symbol内部如果是对象,并且有toString方法,返回的就是这个符号的描述

let a = Symbol({
    a:100,
    toString:function () {
        return "symbol 的描述信息"
    }
})
console.log(a)

//返回--------------Symbol(symbol 的描述信息)

4.3 Symbol内部如果是数组,内部的参数会被扁平化,用逗号隔开

let a = Symbol([
    1,2,3,'a','v','c'
])
console.log(a)

/返回------------Symbol(1,2,3,a,v,c)

5、Symbol的应用场景

用Symbol来创建对象的内部属性,内部属性的特点是防止外部获取或者随意篡改

let sym = Symbol("objKey")
let obj = {
    a:100,
    b:200,
    c:300,
    [sym]:666
}
obj.c = 888;
console.log(obj)
console.log(obj[Symbol("objKey")])

symbol定义的属性,外部是无法获取的,因为symbol同值是不相等的。即:symbol("objKey") != symbol("objKey")

对象遍历symbol的时候是得不到这个key

let sym = Symbol("objKey")
let obj = {
    a:100,
    b:200,
    c:300,
    [sym]:666
}
obj.c = 888;
for(let item in obj){
    console.log(item)
}

Object.keys方法也不能获取symbol对应的key

console.log(Object.keys(obj))

6、获取对象中Symbol的key的方法

6.1 Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols,返回的是只有symbol定义的key

    let sym = Symbol("objKey")
    let obj = {
        a:100,
        b:200,
        c:300,
        [sym]:666
    }
    console.log(Object.getOwnPropertySymbols(obj))

6.2 Reflect.ownKeys(obj)

Reflect.ownKeys,返回的是所有的key,包含symbol定义的key

let sym = Symbol("objKey")
let obj = {
    a:100,
    b:200,
    c:300,
    [sym]:666
}
console.log(Reflect.ownKeys(obj))

获取对象中symbol对应的值

    let sym = Symbol("objKey")
    let obj = {
        a:100,
        b:200,
        c:300,
        [sym]:666
    }
    let num = obj[Object.getOwnPropertySymbols(obj)[0]];
    console.log(num) ///666

7、共享符号

普通符号

let a = Symbol()

共享符号

let a = Symbol.for()

.for()就代表创建了一个共享的符号,内部参数也是描述信息

    let symFor = Symbol.for("Symbol");
    let symFor2 = Symbol.for("Symbol");
    console.log(symFor == symFor2) ///true

上面的结果返回的是true,机理是:Symbol.for()定义的符号代表共享符号,如果创建了共享符号,此时就相当于在 全局创建了一个符号,此时如果再次创建相同描述的符号,就不会再创建新的了,而是将原来的抛出,所以结果是相等的

Symbol.keyFor()

Symbol.keyFor()方法来获取已经注册到全局的共享符号的描述信息

    let symFor = Symbol.for("Symbol");
    let symFor2 = Symbol.for("Symbol");
    console.log(Symbol.keyFor(symFor))
///Symbol

8、Symbol的注意事项

8.1 Symbol值不能与其他类型的值进行运算,会报错

var sym = Symbol('My symbol');
"your symbol is " + sym  // 报错Cannot convert a Symbol value to a string

8.2 Symbol值可以显式转为字符串

var sym = Symbol('My symbol');
String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'

8.3、Symbol值也可以转为布尔值,但是不能转为数值

var sym = Symbol();
Boolean(sym) // true

Number(sym) // TypeError
sym + 2 // TypeError

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值