symbol数据类型

symbol的定义

symbol(符号)是es6新增的数据类型,符号是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。

一般情况下,重复的属性,后面的会把前面的覆盖掉

let grade = {
    lisi: {js:100,css:89},
    lisi:{js:35,css:55}
}
console.log(grade["lisi"]);

//{js:35,css:55}

而使用symbol则不会,因为symbol实例是唯一的

在对象中用[ ]括起来,表示该属性是变量,不然会当该属性为字符串

在对象中直接使用symbol实例也要用[ ]括起来

let grade = {
[Symbol('foo')]: {js:100, css: 89 },
[Symbol('bar')]: { js: 35, css: 55 }
};

 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[user1.key]);
    
    //{ js: 100, css: 89 }

遍历symbol属性

symbol不能使用for/in、for/of直接遍历操作

let symbol = Symbol("demo");
let obj = {
  name: "lisi",
  [symbol]: "haha"
};

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

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

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

for (const key of Object.getOwnPropertySymbols(obj)) {
  console.log(key);
}
//Symbol(demo)

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

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

因此symbol跟私有属性有点类似,如果对象属性不想遍历,可以使用symbol保护起来

全局符号注册表

如果运行时的不同部分需要共享和重用符号实例,那么可以用一个字符串作为键,在全局符号注册表中创建并重用符号。

因此,需要使用Symbol.for()方法。第一次使用某个字符串调用时,它会检查全局运行时注册表,发现不存在对应的符号,于是就会生成一个新符号实例并添加到注册表中。后续使用相同字符串的调用同样会检查注册表,发现存在与该字符串对应的符号,然后就会返回该符号实例。

let one = Symbol.for('demo');
let two = Symbol.for('demo');
console.log(one === two);
//true

如果不是使用Symbol.for()方法在全局中注册的话,定义的符号也并不相等。

let one = Symbol.for('demo');
let two = Symbol('demo')
console.log(one === two);
//false
posted @ 2021-02-06 21:48  Hhhighway  阅读(400)  评论(0编辑  收藏  举报