ES6-11学习笔记--Symbol

Symbol:一种新的原始数据类型   声明方式:
let s1 = Symbol()
let s2 = Symbol()
console.log(s1); // Symbol()
console.log(s2); // Symbol()
console.log(s1 === s2); // false

let s3 = Symbol('foo');
let s4 = Symbol('bar');
console.log(s3); // Symbol(foo)
console.log(s4); // Symbol(bar)
console.log(s3 === s4); // false

  

如果Symbol声明时传入的参数是对象,会自动调用自身的toString方法:
const obj = {
    name: '张三'
}
let s5 = Symbol(obj)
console.log(s5); // Symbol([object Object])

  

for方法: 使用for方法会在全局进行表述的定义,下次再使用for定义,会先去全局定义里面找有没有定义过的描述
let s6 = Symbol.for('foo')
let s7 = Symbol.for('foo')

function foo() {
    return Symbol.for('foo')
}
s8 = foo()
console.log(s6 === s7); // true
console.log(s6 === s8); // true

  

keyFor来查看你的Symbol有没在全局登记过:
const s9 = Symbol('foo')
const s10 = Symbol.for('foo')
console.log(Symbol.keyFor(s9)); // undefined
console.log(Symbol.keyFor(s10)); // foo

  

应用场景:   1、用Symbol保证对象的Key可以重名但是Key不相等,得到同时存在, 例如一个对象里面保存班级同学的信息,但是很有可能班级有重名的情况
const stu1 = Symbol('张三')
const stu2 = Symbol('张三')
const grade = {
    [stu1]: {
        address: 'aaa',
        tel: '111'
    },
    [stu2]: {
        address: 'bbb',
        tel: '222'
    },
}
console.log(grade);
console.log(grade[stu1]);
console.log(grade[stu2]);

  

2、使用Symbol可以相对隐藏类的实例属性

const sym = Symbol('age')
class User {
    constructor(name) {
        this.name = name
        this[sym] = 18
    }
    getName() {
        console.log('getName:' + this.name + ' age:' + this[sym])
    }
}

const user = new User('张三')
user.getName()
// for in是读取不到sym属性
for (let key in user) {
    console.log(key);
}
// keys读取不到sym属性
for (let key of Object.keys(user)) {
    console.log(key);
}
// getOwnPropertySymbols只能读取Symbol属性
for (let key of Object.getOwnPropertySymbols(user)) {
    console.log(key);
}
// Reflect.ownKeys既可以读取一般实例属性,也可以读取Symbol属性
for (let key of Reflect.ownKeys(user)) {
    console.log(key);
}

  

3、消除魔术字符串

什么是魔术字符串?如下代码:

这里的aaa,bbb就是魔术字符串,需要来回编写,而且只要原方法修改,另外地方也要跟着修改
function getArea(str) {
    let area = 0
    switch (str) {
        case 'aaa':
            area = 1
            break
        case 'bbb':
            area = 2
            break
    }
    return area
}
console.log(getArea('aaa'))

  

使用对象来消除魔术字符串
/* 
const strType = {
    aaa: 'aaa',
    bbb: 'bbb',
} 
*/
// 由于上面value其实并不需要关心是什么字符串,所以可以用Symbol来代替
const strType = {
    aaa: Symbol(),
    bbb: Symbol(),
}

function getArea2(str) {
    let area = 0
    switch (str) {
        case strType.aaa:
            area = 1
            break
        case strType.bbb:
            area = 2
            break
    }
    return area
}
console.log(getArea2(strType.aaa))

  

上一篇:Symbol


下一篇:Symbol类型