ES6 中的 Symbol 性质及使用技巧

前言

Symbol 是 ECMAScript 6 中新增的数据类型,它主要用于表示唯一的标识符,是一种基本数据类型,可以通过 Symbol 函数来创建。由于 Symbol 创建的变量是独一无二的,它可以被用来作为对象属性的键,并可以防止属性冲突的问题。

Symbol 的基本性质

以下是 Symbol 的基本性质:

  1. Symbol 值是独一无二的,通过 Symbol 函数创建的每个 Symbol 值都是唯一的,即使创建时传入相同的字符串作为参数,也会生成不同的 Symbol 值。
const symbol1 = Symbol('foo');
const symbol2 = Symbol('foo');

console.log(symbol1 === symbol2); // false
  1. Symbol 是一种基本数据类型,它不是对象,没有属性和方法。
const symbol = Symbol('foo');

console.log(symbol.prop); // undefined
console.log(symbol.method()); // TypeError: symbol.method is not a function
  1. Symbol 可以作为对象属性的键,这种属性称为 Symbol 属性,它不会出现在 for...in 循环、Object.keys()、Object.getOwnPropertyNames() 等方法返回的结果中,但可以通过 Object.getOwnPropertySymbols() 方法获取对象的所有 Symbol 属性,也可使用 Reflect.ownKeys() 方法获取对象的所有键,包括 Symbol 属性和非 Symbol 属性。
const symbol = Symbol('foo');
const obj = {
  [symbol]: 'bar',
  prop: 'value'
};

console.log(obj[symbol]); // 'bar'
console.log(obj.prop); // 'value'
console.log(Object.keys(obj)); // ['prop']
console.log(Object.getOwnPropertyNames(obj)); // ['prop']
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(foo)]
console.log(Reflect.ownKeys(obj)); // ['prop', Symbol(foo)]
  1. Symbol 属性不能够使用点运算符直接访问,必须使用方括号语法。
const symbol = Symbol('foo');
const obj = {
  [symbol]: 'bar'
};

console.log(obj.symbol); // undefined
console.log(obj[symbol]); // 'bar'

Symbol 的使用技巧

  1. Symbol 常用作对象属性的键,用于防止属性冲突。
const color = {
  red: 'red',
  green: 'green',
  blue: 'blue'
};

const symbol = {
  red: Symbol('red'),
  green: Symbol('green'),
  blue: Symbol('blue')
};

const obj = {
  [symbol.red]: 'This is red',
  [symbol.green]: 'This is green',
  [symbol.blue]: 'This is blue'
};

console.log(obj[symbol.red]); // 'This is red'
console.log(obj[symbol.green]); // 'This is green'
console.log(obj[symbol.blue]); // 'This is blue'
console.log(obj[color.red]); // undefined
console.log(obj[color.green]); // undefined
console.log(obj[color.blue]); // undefined
  1. Symbol 可以用来定义常量,在创建 Symbol 时传入相同的字符串作为参数,就可以创建一个相同的 Symbol 值。
const MY_COOL_CONSTANT = Symbol('my cool constant');

console.log(MY_COOL_CONSTANT === MY_COOL_CONSTANT); // true

const obj = {
  [MY_COOL_CONSTANT]: 'This is my cool constant'
};

console.log(obj[MY_COOL_CONSTANT]); // 'This is my cool constant'
  1. Symbol 可以用来定义类方法名、私有属性或者自定义对象迭代器等。
class MyClass {
  [Symbol.myMethod]() {
    console.log('My method');
  }
}

const obj = new MyClass();
obj[Symbol.myMethod](); // 'My method'

class MyClass2 {
  #myPrivateProperty = 'private';

  [Symbol.iterator]() {
    let index = 0;

    const values = Object.values(this.#myPrivateProperty);

    return {
      next: () => ({
        value: values[index++],
        done: index > values.length
      })
    };
  }
}

const obj2 = new MyClass2();
console.log([...obj2]); // ['p', 'r', 'i', 'v', 'a', 't', 'e']

总结

Symbol 是一种新的基本数据类型,它主要用于对象属性键的唯一性,可以有效地避免键名冲突的问题。在实际开发中,我们可以使用 Symbol 建立自己的命名空间、创建常量等。同时,还可以利用 Symbol 来定义类方法名、私有属性和自定义对象迭代器等功能。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b8c1faadd4f0e0ff155b58