ES6 新增加的数据类型——Symbol

目录

基本概念

1. 创建方法

2. 特性

 具体用法

1. 避免产生属性冲突

2. for..in 遍历时会隐藏

3. Symbol 的获取

4. for...of 遍历


基本概念

1. 创建方法

  • 符号是原始值,直接用 Symbol() 函数创建

  • 因为是原始类型,所以用 typeof 判断数据类型

let sym = Symbol();
console.log(typeof sym);    // symbol
  • 不能用 new 关键字是为了避免创建符号包装对象。其实像 Boolean String Number 也是原始数据类型,但它们可以用 new 关键字

let myBoolean = new Boolean();
console.log(typeof myBoolean);   // object

let myString = new String();
console.log(typeof myString);   // object

let myNumber = new Number();
console.log(typeof myNumber);  // object

2. 特性

  • 实例唯一且不可变,可以接收一个可选参数,方便代码阅读和后期调试,即便参数值一样,两个 symbol 变量也是不一样的
let sym1 = Symbol();
let sym2 = Symbol();
console.log(sym1 == sym2);     // false


let sym3 = Symbol('foo');
let sym4 = Symbol('foo');
console.log(sym3 == sym4);    // false
  • Symbol.for() 创建共享 Symbol , 如果已存在,直接返回已有的 Symbol 
let sym1 = Symbol.for('foo');
let sym2 = Symbol.for('foo');   // 已经有同样标记为 'foo' 的 Symbol ,返回 sym1 给 sym2,实现共享
console.log(sym1 == sym2);      // true 

// 但是混用是不生效的
let sym3 = Symbol('foo');
let sym4 = Symbol.for('foo');
console.log(sym3 == sym4);     // false 因为 sym3 并不共享

 具体用法

1. 避免产生属性冲突

  • 由于 Symbol 的唯一性,所以可以用来确保对象属性使用唯一标识符,避免产生属性冲突的危险。
// 给对象添加 Symbol 类型的属性
let level1 = Symbol('level');
let level2 = Symbol('level');      // level1 和 level2 变量都是表示 参数为 level 的 Symbol 变量

const student =  {
    name: 'mike',
    age: 15,
    [level1]: '优秀',
    [level2]: '富有'            // 即便二者都为 参数为 level 的 Symbol 变量,但是由于 Symbol 的唯一性,所以不会尝试属性冲突
}
console.log(student);          // { name: 'mike', age: 15, [Symbol(level)]: '优秀', [Symbol(level)]: '富有' }

// 同时上面的代码可以直接简写为
const student =  {
    name: 'mike',
    age: 15,
    [Symbol('level')]: '优秀',
    [Symbol('level')]: '富有'            // 即便二者都为 参数为 level 的 Symbol 变量,但是由于 Symbol 的唯一性,所以不会尝试属性冲突
}
console.log(student);          // { name: 'mike', age: 15, [Symbol(level)]: '优秀', [Symbol(level)]: '富有' }

2. for..in 遍历时会隐藏

像对于一些不想要让他人知道的信息可以用 Symbol ,这样在 for...in 遍历中不会显现出来

例如上面例子中对于学生等级的划分

const student =  {
    name: 'mike',
    age: 15,
    [Symbol('level')]: '优秀',
    [Symbol('level')]: '富有'
}           

for(let pro in student) {
    console.log(pro);
}

// name
// age
  • 同时 Object.keys() ,Object.getOwnPropertyNames() 也都无法显示 Symbol 类型的属性名
const student =  {
    name: 'mike',
    age: 15,
    [Symbol('level')]: '优秀',
    [Symbol('level')]: '富有'
}           

console.log(Object.keys(student));                  // [ 'name', 'age' ]
console.log(Object.getOwnPropertyNames(student));   // [ 'name', 'age' ]
  • 不能用 for... of 遍历,会报错,因为 student 是一个对象,没有 Symbol.iterator 属性,for...of 遍历的是有迭代器的

3. Symbol 的获取

  • 通过 Object.getOwnPropertySymbols() 能获取到对象中 Symbol 类型的属性,返回值是一个数组。
const student =  {
    name: 'mike',
    age: 15,
    [Symbol('level')]: '优秀',
    [Symbol('level')]: '富有'
}           

let symList = Object.getOwnPropertySymbols(student);

for(let i of symList) {
    console.log(i);
}
// Symbol(level)
// Symbol(level)

// 通过访问属性可以获取属性值
for(let i of symList) {
    console.log(student[i]);
}
// 优秀
// 富有

4. for...of 遍历

  • 如果对象有 Symbol.iterator 属性 就可以被 for...of 遍历
  • for...of 遍历前就是判断对象是否有 Symbol.iterator 属性
const student =  {
    name: 'mike',
    age: 15,
    [Symbol('level')]: '优秀',
    [Symbol('level')]: '富有'
} 

const list = [1,2,3,4,5];

console.log(student[Symbol.iterator]);       // undefined
console.log(list[Symbol.iterator]);          // [Function: values]

// student 用 for...of 遍历会报错
// list 不会报错
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值