Symbol用于防止属性名冲突而产生的,Symbol的值是唯一的、独一无二的,不会重复。
Symbol是ES6中新增的一种数据类型, 被划分到了基本数据类型

基本数据类型: 字符串、数值、布尔、undefined、null、Symbol

引用数据类型: Object

1.基础知识

  1. Symbol 的值是唯一的,独一无二的不会重复的
let hd = Symbol();
let edu = Symbol();
console.log(hd); //symbol
console.log(hd == edu); //false
  1. Symbol 不可以添加属性
let hd = Symbol();
hd.name = "xxxx";
console.log(hd.name);//undefined
  1. 可传入字符串用于描述Symbol,方便在控制台分辨Symbol
  2. 传入相同参数Symbol也是独立唯一的,因为参数只是描述而已,但使用 Symbol.for则不会
  3. 使用description可以获取传入的描述参数
let zz = Symbol("is name");
        let edu = Symbol("这是一个测试");
        let xx = Symbol("is name")
        console.log(zz); //Symbol(is name)
        console.log(edu.toString()); //Symbol(这是一个测试)
        console.log(zz === xx);//false
          console.log(edu.description);// 这是一个测试
  1. Symbol 是独一无二的所以可以保证对象属性的唯一。

Symbol 声明和访问使用 [](变量)形式操作

也不能使用 . 语法因为 .语法是操作字符串属性的。

下面写法是错误的,会将symbol 当成字符串symbol处理

let symbol = Symbol("后盾人");
let obj = {
  symbol: "hdcms.com"
};
console.log(obj);

正确写法是以[] 变量形式声明和访问

let symbol = Symbol("后盾人");
let obj = {
  [symbol]: "houdunren.com"
};
console.log(obj[symbol]); //houdunren.com

2.Symbol的方法

2.1 Symbol.for

根据描述获取Symbol,如果不存在则新建一个Symbol
使用Symbol.for会在系统中将Symbol登记
使用Symbol则不会登记

let hd = Symbol.for("后盾人");
let edu = Symbol.for("后盾人");
console.log(hd == edu); //true

2.2Symbol.keyFor

Symbol.keyFor 根据使用Symbol.for登记的Symbol返回描述,如果找不到返回undefined 。

let hd = Symbol.for("后盾人");
console.log(Symbol.keyFor(hd)); //后盾人

let edu = Symbol("houdunren");
console.log(Symbol.keyFor(edu)); //undefined

3.Symbol的遍历

Symbol 不能使用 for/in、for/of 遍历操作**,对象里如果有Symbol属性的键, 使用for/in,for/in是遍历不到这个属性(键)的**

let symbol = Symbol("后盾人");
let obj = {
  name: "hdcms.com",
  [symbol]: "houdunren.com"
};

for (const key in obj) {
  console.log(key); //name
}

for (const key of Object.keys(obj)) {
  console.log(key); //name
}

3.2 Object.getOwnPropertySymbols

可以使用 Object.getOwnPropertySymbols 获取所有Symbol属性

let name=Symbol('name')
        let obj={
            [name]:'xz',
            age:'22',
            sex:'男',
        }
        
        for (const key of   Object.getOwnPropertySymbols(obj)) {
                console.log(key);//Symbol(name)
                console.log(obj[key]);//xz
        }

		 for (const key in   Object.getOwnPropertySymbols(obj)) {
                console.log(key);//0
                console.log(obj[key]);//undefined
        }

3.3 Reflect.ownKeys(obj)

也可以使用 Reflect.ownKeys(obj) 获取所有属性包括Symbol

...
for (const key of Reflect.ownKeys(obj)) {
  console.log(key);// age ,sex,Symbol(name)
}
...

3.Symbol的应用

1.symbol可以用在给对象设置一个唯一的key

这里是一个数据缓存的例子,例如user.name和car.name,一个是用户名为apple,一个是物品的名为apple,将其放入缓冲中,如果根据对象的name属性放入缓存中,data[name]就会发生覆盖,所以可以设置一个key值,值为Symbol,永远不会重复

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


        //在对象里面设置一个symbol ,存放时就用user.key来命名,取出时也是,就不会出现重复得情况 
            let user={
                name:'apple',
                des:'people',
               key:Symbol('people')
            }
            let cart={
                name:'apple',
                des:'cart',
                key:Symbol('people')
            }

2.如果对象属性不想被遍历,可以使用Symbol保护

const site = Symbol("网站名称");
class User {
  constructor(name) {
    this[site] = "zzz";
    this.name = name;
  }
  getName() {
    return `${this[site]}-${this.name}`;
  }
}
const hd = new User("xxx");
console.log(hd.getName());//zzz-xxx
console.log(hd[site]);//zzz  可以访问到,但是遍历不到
for (const key in hd) { // for of 会报错
  console.log(key);//name
}