js--Symbol

174 阅读2分钟

Symbol

对象的属性键只能是字符串和symbol类型。

symbol值表示唯一的标识。

创建

语法: let id = Symbol([description])

symbol值通过 symbol函数生成。

let id = Symbol()
// Symbol()

symbol函数不能使用new 命令。symbol是个原始类型。

description

symbol函数可以接受一个字符串作为参数。

参数只是一个标签,不影响任何东西。目的是便于区分。

let id = Symbol("id")
// Symbol(id)

参数相同Symbol函数返回的值也是不同的。

let id = Symbol()
let id1 = Symbol()
  id === id1
  // false
let id2 = Symbol('id2')
let id3 = Symbol('id2')
id2 === id3
// false

如果参数为对象,会调用该对象的toString()方法转化为字符串,再生成Symbol值。

let obj = {age:99}
let id = Symbol(obj)
// Symbol([object Object])
let obj1 = {
     age:88,
     toString(){
      return 'age:'+this.age
     }
}
let id1 = Symbol(obj1)
// Symbol(age:88)

其他

Symbol 值不能与其他类型的值进行运算。

let id = Symbol('id')
id+0
// Uncaught TypeError: Cannot convert a Symbol value to a number
id+ ''
// Uncaught TypeError: Cannot convert a Symbol value to a string

Symbol 值可以显式使用toString,String的方式转为字符串。

也可以转为布尔值。数值不可以。

Symbol('id').toString()
String(Symbol('id'))
// "Symbol(id)"
// "Symbol(id)"

可以通过Symbol值的description获取参数。

let id = Symbol('id')
id.description
// "id"

全局 symbol

有时我们想要名字相同的 Symbol 具有相同的实体,可以创建全局symbol。

Symbol.for

语法:let id = Symbol.for(key)

该调用会检查全局注册表,如果有一个描述为 key的 Symbol,则返回该 Symbol,否则将创建一个新 Symbol,并通过给定的 key 将其存储在注册表中。

let id = Symbol.for('id')
let s = Symbol.for('id')
id === s
// true

Symbol.keyFor

语法:let key = Symbol.keyFor(val)

Symbol.keyFor用于根据指定的symbol值获取key。(不适用于非全局Symbol)

let id = Symbol.for('id')
let key = Symbol.keyFor(id)
key
// "id"

对象属性

使用Symbol创建的属性,代码的任何其他部分都不能意外访问或重写这些属性。 Object.assign 会同时复制字符串和 symbol 属性

Symbol 在 for…in ,Object.keys()中会被跳过

let obj = {
    name: '红雷',
    [Symbol('id')]: '扫黑除恶'
   }
  for (const key in obj) {
      console.log(key) //name
  }
  console.log(Object.keys(obj)) //["name"]
 console.log(Object.getOwnPropertyNames(obj)) // ["name"]

遍历出Symbol键

Object.getOwnPropertySymbols(obj) // 遍历出对象所有Symbol键。

Reflect.ownKeys(obj) // 遍历出对象所有键包括Symbol键。

let obj = {
    name: '红雷',
    [Symbol('id')]: '扫黑除恶'
   }
 console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(id)]
 console.log(Reflect.ownKeys(obj)) // ["name", Symbol(id)]

Symbols 与 JSON.stringify()

当使用 JSON.stringify() 时,以 symbol 值作为键的属性会被完全忽略。

JSON.stringify({[Symbol("id")]: "id"});
// "{}"

系统Symbol

  • Symbol.iterator 迭代
  • Symbol.toPrimitive 一个将对象转化为基本数据类型的方法。
  • ……等等。