【ES6】Symbol

介绍

  • 自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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值