ES6 symbol的作用

98 阅读3分钟

ES6 symbol的作用

ES6 引入了 Symbol 类型,它是一种新的原始数据类型,用于创建唯一的、不可变的值。Symbol 的主要作用是作为对象属性的唯一标识符,避免属性名冲突,同时也可以用于定义一些特殊的行为(如自定义迭代器)。

以下是 Symbol 的主要作用和应用场景:

  1. 创建唯一的属性键

Symbol 的主要用途是作为对象属性的键,确保属性名不会与其他属性名冲突。因为每个 Symbol 值都是唯一的,即使它们的描述相同。

示例:

const id = Symbol('id'); // 创建一个 Symbol,描述为 'id'
const user = {
    name: 'Alice',
    [id]: 123 // 使用 Symbol 作为属性键
};

console.log(user[id]); // 123
console.log(Object.keys(user)); // ['name'],Symbol 属性不会被枚举
  1. 避免属性名冲突

在大型项目中,可能会在不同的模块中使用相同的字符串作为属性名,这可能导致属性名冲突。使用 Symbol 可以避免这种问题,因为每个 Symbol 都是唯一的。

示例:

const module1 = {
    id: 1
};

const module2 = {
    id: 2
};

// 使用 Symbol 避免冲突
const id = Symbol('id');
module1[id] = 1;
module2[id] = 2;

console.log(module1[id]); // 1
console.log(module2[id]); // 2
  1. 定义对象的私有属性

Symbol 可以用作对象的私有属性,因为 Symbol 属性不会被常规方法(如 for...inObject.keys()Object.getOwnPropertyNames())枚举到。

示例:

const age = Symbol('age');

const person = {
    name: 'Alice',
    [age]: 25
};

console.log(person[age]); // 25

for (let key in person) {
    console.log(key); // 只输出 'name'
}
  1. 内置 Symbol 值

ES6 提供了一些内置的 Symbol 值,用于定义对象的特殊行为。这些内置 Symbol 值被称为“Well-Known Symbols”,例如:

  • Symbol.iterator:定义对象的默认迭代器。
  • Symbol.toStringTag:定义对象的 toString 行为。
  • Symbol.hasInstance:定义 instanceof 的行为。

示例:

// 自定义对象的迭代行为
const myIterable = {
    [Symbol.iterator]: function* () {
        yield 1;
        yield 2;
        yield 3;
    }
};

for (let value of myIterable) {
    console.log(value); // 1, 2, 3
}
  1. 全局 Symbol 注册表

ES6 提供了 Symbol.for()Symbol.keyFor() 方法,用于创建和访问全局 Symbol 注册表中的 Symbol 值。

  • Symbol.for(key):如果全局注册表中存在与 key 对应的 Symbol,则返回它;否则创建一个新的 Symbol 并注册。
  • Symbol.keyFor(sym):返回全局注册表中与 sym 对应的 key

示例:

const sym1 = Symbol.for('mySymbol'); // 创建或获取全局 Symbol
const sym2 = Symbol.for('mySymbol');

console.log(sym1 === sym2); // true

console.log(Symbol.keyFor(sym1)); // 'mySymbol'
  1. Symbol 的特性
  • 唯一性:每个 Symbol 值都是唯一的,即使它们的描述相同。
  • 不可变性Symbol 值是不可变的,不能被修改。
  • 不可枚举性Symbol 属性不会被 for...inObject.keys() 等枚举到。
  • 类型检测typeof Symbol() 返回 'symbol'

示例:

const sym1 = Symbol('foo');
const sym2 = Symbol('foo');

console.log(sym1 === sym2); // false,Symbol 是唯一的
console.log(typeof sym1); // 'symbol'
  1. Symbol 的应用场景
  • 避免属性名冲突:在大型项目或库中,使用 Symbol 作为属性键可以避免命名冲突。
  • 定义私有属性Symbol 属性不会被常规方法枚举,适合用于定义私有属性。
  • 自定义对象行为:通过内置 Symbol 值(如 Symbol.iterator)可以定义对象的特殊行为。
  • 元编程Symbol 可以用于定义对象的元数据或特殊行为。

总结

Symbol 是 ES6 引入的一种新的原始数据类型,主要用于创建唯一的属性键,避免属性名冲突,同时也可以用于定义对象的特殊行为(如迭代器)。它的唯一性和不可枚举性使其非常适合用于定义私有属性或元数据。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github