https://www.bilibili.com/video/av75170134?from=search&seid=1433232185588486261

在线文档:http://houdunren.gitee.io/note/js/5%20Symbol.html

1. Symbol 使用场景介绍

永远不会重复的字符串

2. 声明定义 Symbol 的几种方式

# 定义

let hd = Symbol('后盾人在线教程');
let edu = Symbol('网址是houdunren.com');

// symbol 当成 '永远不会重复的字符串'
// 不能自定义属性
// 但是能调用默认的属性

console.log(hd)
console.log(hd.toString()) ;
console.log(hd.description) ;

let a = Symbol.for('hdcms') ;
console.log(a) ;

区别:
1、内存定义的区别

  • Symbol('xxx') 字段相同,指向不同(底层开辟新空间)
  • Symbol.for('xxx') 字段相同,指向相同(如果已有,指向已有空间)
let a = Symbol('aaa') ; 
let b = Symbol('aaa') ;
console.log(a==b) ; //false 

let aa = Symbol.for('bbb') ; 
let bb = Symbol.for('bbb') ; 
console.log(aa==bb) ; //true


2、 获取的区别:

let hd = Symbol('后盾人在线教程');

console.log(hd.description) ;
console.log(Symbol.keyFor(hd));


let cms = Symbol.for('aaa') ; 
console.log(cms.description) ; 
console.log(Symbol.keyFor(cms)) ; 

# 获取

let hd = Symbol('后盾人在线教程');

console.log(hd.description) ;
console.log(Symbol.keyFor(hd));


let cms = Symbol.for('aaa') ; 
console.log(cms.description) ; 
console.log(Symbol.keyFor(cms)) ; 

3. 使用 Symbol 解决字符串耦合问题

let user1 = {
    name: '李四',
    key: Symbol() 
}
let user2 = {
    name: '李四' , 
    key: Symbol() 
}
let grade = {
    [user1.key]: {js: 100, css: 89},
    [user2.key]: {js: 35 , css: 55}
}
console.log(grade) ;
console.log(grade[user1.key]) ;

4. Symbol 在缓存容器中的使用

class Cache{
    static data = {} ; 
    static set(name, value) {
        return (this.data[name]=value) ;
    }
    static get(name){
        return this.data[name] ;
    }
}

// Cache.set('hdcms', 'houdunren.com') ; 
// console.log(Cache.get('hdcms')) ; 

let user= {
    name:'apple',
    desc: '用户资料',
    key:Symbol('会员资料')
};
let cart = {
    name:'apple',
    desc: '购物车',
    key:Symbol('购物车数据')
}; 
//1
Cache.set('user-apple',user);
Cache.set('cart-apple',cart) ;
//2 
Cache.set(user.key,user); 
Cache.set(cart.key,cart);
console.log(Cache.get(user.key).desc) ;

5. 扩展特性与对象属性保护

# Object.keys、Object.getOwnPropertySymbols 、 Reflect.ownKeys

let symbol = Symbol('这是一个Symbol类型');
let hd = {
    name: '后盾人' ,
    [symbol]: 'houdunren.com'
};
for(const key in hd) {// 获取普通属性
    console.log(key) ; 
}
console.log('--')
for (const key of Object.keys(hd)) { // 获取普通属性
    console.log(key) ; 
}
console.log('--'); 
for(const key of Object.getOwnPropertySymbols(hd)) { // 获取 symbol 属性
    console.log(key);
}
console.log('--'); 
for(const key of Reflect.ownKeys(hd)) { // 获取全部(普通+symbol)属性
    console.log(key) ;
}

let site = Symbol('这是一个Symbol') ; 
class User {
    constructor(name) {
        this.name = name ; 
        this[site] = '后盾人';
    }
    getName() {
        return `${this[site]} ${this.name}` ; 
    }
}

let edu = new User('李四') ;
console.log('----')
console.log(edu.getName()) ; 
console.log('----')
console.log(edu) ; //看到 symbol
for(const key in edu) {
    console.log(key);
}