介绍
- 自es6开始,JavaScript新增了一个
基本数据类型
Symbol,用于实现一个唯一不重复不可变的值,成为了js的第六个基本数据类型(string,number,boolean,null,undefined) - 任何一个Symbol都是一个唯一不相等的值(不与其他symbol值相等)
1-1 创建Symbol
- 创建局部的Symbol----使用Symbol函数创建
let sy = Symbol ( ‘描述’ ) ;
// 创建局部Symbol
let n3 = Symbol('123');
let n4 = Symbol('123');
/*
使用symbol类型的数据都是具有唯一性的,是独一无二的。就算描述相同*/
console.log(n3 === n4);//false
普通声明
let n1 = 123;
let n2 = 123;
console.log(n1 === n2);//true
// 证明两个变量存储的值及值类型都是相同的
- 创建全局的Symbol
let sy = Symbol.for ( ‘描述’ ) ;
这里使用Symbol.for()
来创建Symbol值
// 创建全局Symbol-----利用Symbol.for创建新的Symbol值
let a1 = Symbol.for('demo');
// 先检测是否有符合'demo'的描述的Symbol值,
// 没有则创建描述'demo'的描述的Symbol值
let a2 = Symbol.for('demo');
// 后检测到有符合描述'demo'的symbol值,返回该symbol值
// 因为a1和a2接收的都是一个唯一的Symbol值,所以比较为true
console.log(a1 === a2);//true
Symbol.for();可以全局检测是否创建了括号中符合描述字段的symbol值,
如果有则返回该symbol值,没有则重新创建一个symbol值
1-2 作用
- 作为对象的属性名使用,把一些不需要对外操作和访问的属性使用Symbol来定义,因为Symbol类型的key是不能通过Object.keys()或者for…in…来枚举到
- 由于每一个Symbol的值都是不相同的,当使用symbol作为对象属性名时,可以保证属性名不重名
1-3 使用
- 场景:定义对象时直接创建Symbol值
// 对象添加Symbol方法一
let par2 = Symbol('par2');
let par1 = Symbol('par1');
let obj = {
[par1]: 'tom',
[par2]: 'andy'
}
console.log('obj1', obj);
//obj1 { [Symbol(par1)]: 'tom', [Symbol(par2)]: 'andy' }
- 场景:有一个对象ob1,在不清楚其内部是否包含属性par1的情况下添加一个属性par1,不能覆盖原属性
// 对象添加Symbol方法二
let par2 = Symbol('par2');
let par1 = Symbol('par1');
let obj2 = {
par1: '我是原本就有的属性',
}
obj2[par1] = 'hello';
obj2[par2] = 'Symbol';
console.log('obj2', obj2.par1);
//obj2 '我是原本就有的属性'
// 获取Symbol值
console.log(obj2[par1], obj2[par2]);
//hello Symbol
// 直接点属性是不能获取到Symbol值的
console.log(obj2.par2);
//undefined
// 修改Symbol值
obj2[par1] = 'xiaoxiao';
console.log(obj2);
//{par1: '我是原本就有的属性', Symbol(par1): 'xiaoxiao', Symbol(par2): 'Symbol'}
Symbol 作为对象属性名时不能用.
运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 par2属性,而不是 Symbol 值 par2属性。
- 在类中可以类比成私有属性使用(新的es版本中已经有私有属性的定义方法了)
// 在类中类比为私有属性使用(新的es版本中已经有私有属性的定义方法了)
let Fun = (function(){//闭包
//创建私有属性
const PWD = Symbol();
class Demo{
constructor(uname,password){
this.uname = uname;
//私有属性赋值
this[PWD] = password;
}
//get 获取私有属性值
get userPwd(){
return `用户的密码属于私有信息,获取的密码为${this[PWD]}`
}
}
//将类的实例返回
return Demo;
})()
let demo1 = new Fun('tom','zhangsan');
console.log(demo1.uname);//tom
console.log(demo1.PWD);//undefined
// console.log(demo1[PWD]);//PWD is not defined
console.log(demo1.userPwd)//用户的密码属于私有信息,获取的密码为zhangsan
1-4 Symbol循环遍历
注意
:常规的(for…in…)(Object.keys())是不能遍历出Symbol类型的属性的
- for in ---- 只能遍历出对象的普通属性
// 定义对象和Symbol值
let c1 = Symbol('number'),
c2 = Symbol('string'),
c3 = Symbol('function');
let obj3 = {
[c1]: 10,
c1: '12',
[c2]: 'hello Ajax',
c2: true,
[c3]: () => {
console.log('一个函数');
},
c3: function () {
console.log(1 + 1 + 1);
}
}
console.log(obj3);
/*
{
c1: '12',
c2: true,
c3: [Function: c3],
[Symbol(number)]: 10,
[Symbol(string)]: 'hello Ajax',
[Symbol(function)]: [Function: [function]]
}
* */
//遍历 --- for in
for (let k in obj3) {
console.log(`属性${k},值为${obj3[k]}`);
}
/*
* 属性c1,值为12
属性c2,值为true
属性c3,值为function (){
console.log(1+1+1);
}
* */
- Object.keys------只能·遍历出对象普通属性
// 使用Object.keys遍历对象属性
let backArr = Object.keys(obj3);
console.log(backArr);//[ 'c1', 'c2', 'c3' ]
- 使用
Object.getOwnPropertySymbols();
可以遍历出对象中的symbol类型的属性
// 遍历方法 Object.getOwnPropertySymbols
let backArr1 = Object.getOwnPropertySymbols(obj3);
console.log(backArr1);
// [ Symbol(number), Symbol(string), Symbol(function) ]
遍历方法 Object.getOwnPropertySymbols—接收对象, 返回一个数组
- 使用reflect.ownKeys();(反射属性) 遍历对象中的全部属性,包括普通属性和Symbol类型的属性
// Reflect.ownKeys()--------------接收参数obj,返回一个数组
let data = Reflect.ownKeys(obj3);
console.log(data);
//[ 'c1', 'c2', 'c3', Symbol(number), Symbol(string), Symbol(function) ]
1-5 Symbol.for();方法
- 使用这个方法可以检测括号中是否有某个描述的Symbol类型值
// Symbol.for()方法检测对象中是否包含某种描述的Symbol类型的属性
// 有则返回该symbol属性值
// 无则新建并返回一个以该字符串参数为描述的 Symbol 值,
// 并登记在全局环境中供搜索
let cat = Symbol.for('cat');
// 检测--有
let cat1 = Symbol.for('cat');
console.log(cat1);//Symbol(cat)----检测出的
// 检测--无
let pig = Symbol.for('pig');
console.log(pig);//Symbol(pig)---创建的
- 限制多个window对象之间的值唯一性
1-6 Symbol.keyFor();方法
keyFor方法由于返回一个已登记的Symbol类型的描述
let cats = Symbol.for('cat');
// 返回一个已登记的 Symbol 类型值的 描述
let describe = Symbol.keyFor(cats);
console.log(describe);//cat
// 创建一个symbol类型的值,但是并没有写描述
let pigs = Symbol();
let desc = Symbol.keyFor(pigs);
console.log(desc);//undefined