Symbol对象

48 阅读2分钟

Symbol 的一个常见用途是创建对象的私有属性或方法,这些属性或方法不能被外部访问或修改

const animal = {
  [Symbol('name')]: 'Leo',
  [Symbol('age')]: 3,
  [Symbol('getType')]() {
    return 'Mammal';
  }
};

console.log(animal[Symbol('name')]); // undefined
console.log(animal[Symbol('age')]); // undefined
console.log(animal[Symbol('getType')]()); // undefined

console.log(Object.getOwnPropertySymbols(animal)); // [ Symbol(name), Symbol(age), Symbol(getType) ]

  1. Symbol 创建的属性不能被外部访问的主要原因是它们不会出现在对象的常规属性列表
  2. 意味着无法通过常规的属性访问方法(例如点号或方括号)来获取或修改 Symbol 属性的值。

具体来说,以下是 Symbol 属性不能被外部访问的原因:

  1. 唯一性:每个通过 Symbol() 创建的值都是唯一的,即使两个符号具有相同的描述,它们仍然是不同的。因此,除非你拥有对符号的引用,否则无法在外部代码中访问或修改这些符号。
  2. 隐藏性Symbol 属性不会出现在对象的常规属性列表中
  3. 例如 Object.keys()for...in 循环和 Object.getOwnPropertyNames() 方法不会返回 Symbol 属性。
  4. 这使得它们对外部代码是隐藏的,从而保护了它们不被意外访问。

Object. getOwnPropertySymbols

尽管 Symbol 属性不能被直接外部访问,但可以使用 Object.getOwnPropertySymbols()Reflect.ownKeys() 方法来获取对象的所有 Symbol 属性,并进行相应的操作

animal[Object.getOwnPropertySymbols(animal)[0]]//leo

Symbol.iterator

  1. Symbol.iterator 是 ECMAScript 6 中引入的一种特殊的符号(Symbol)
  2. 它用于定义对象的默认迭代器方法。
  3. 所有实现了 Symbol.iterator 方法的对象都被认为是可迭代的(iterable).
  4. 可以通过 for...of 循环或其他迭代器相关的方法进行遍历。
const myiterator = {
    data: ['apple', 'bannana', 'orange'],
    [Symbol.iterator]() {
        let index = 0
        return {
            next: () => {
                if (index < this.data.length) {
                    return { value: this.data[index++], done: false }
                }
                else{
                    return {value:'',done:true}
                }
            }

        }
    }
}
for (const iterator of myiterator) {
    console.log(iterator)
    
}
  1. [Symbol.iterator](){ reutrn { next :()=>{}}}
  2. return {value:,done:}

Symbol的其他用途

  1. 缓存键:在缓存系统中,可以使用 Symbol 作为对象的键,以确保键的唯一性,并避免与其他属性发生冲突。
const cache = {
  [Symbol('userCache')]: {},
  [Symbol('productCache')]: {},
  // 其他缓存...
};

    1. 事件系统:在项目中可以使用 Symbol 创建自定义事件类型,用于实现自定义事件的订阅和发布。