ES6 中的 Symbol:更好的对象属性标识符

在 ES6 中,新增了一种基本数据类型,即 Symbol。Symbol 类型的值是唯一的,可以作为对象属性的标识符,有助于解决对象属性名冲突的问题。本文将详细介绍 Symbol 的使用,以及如何在前端开发中使用它。

Symbol 的基本用法

Symbol 类型的值可以使用 Symbol() 函数来创建。每个 Symbol 值都是唯一的,即使是通过相同的参数创建,也不会相等。

const symbol1 = Symbol();
const symbol2 = Symbol();

console.log(symbol1 === symbol2); // false

Symbol 类型的值可以作为对象属性的标识符。由于 Symbol 值是唯一的,因此可以避免对象属性名冲突的问题。

const mySymbol = Symbol();

const obj = {
  [mySymbol]: 'hello'
};

console.log(obj[mySymbol]); // 'hello'

Symbol 类型的值还可以作为对象的私有属性。由于 Symbol 值是唯一的,因此可以避免其他代码修改私有属性的值。

const mySymbol = Symbol();

class MyClass {
  constructor() {
    this[mySymbol] = 'private';
  }

  getPrivate() {
    return this[mySymbol];
  }
}

const myObject = new MyClass();
console.log(myObject.getPrivate()); // 'private'
console.log(myObject[mySymbol]); // undefined

Symbol 的常用方法

Symbol.for()

Symbol.for() 方法可以根据传入的参数创建或返回一个全局 Symbol 值,如果传入的参数已经存在,则返回已有的 Symbol 值。

const mySymbol = Symbol.for('mySymbol');
const mySymbol2 = Symbol.for('mySymbol');

console.log(mySymbol === mySymbol2); // true

Symbol.keyFor()

Symbol.keyFor() 方法可以返回一个已经注册的 Symbol 值的 key,如果 Symbol 值没有被注册,则返回 undefined。

const mySymbol = Symbol.for('mySymbol');
console.log(Symbol.keyFor(mySymbol)); // 'mySymbol'

const mySymbol2 = Symbol('mySymbol2');
console.log(Symbol.keyFor(mySymbol2)); // undefined

Symbol 的应用场景

私有属性

使用 Symbol 可以实现类似于私有属性的功能。在类的构造函数中,可以使用 Symbol 创建一个唯一的属性标识符,然后在类的方法中使用该属性标识符来访问私有属性。

const privateProperty = Symbol();

class MyClass {
  constructor() {
    this[privateProperty] = 'private';
  }

  getPrivate() {
    return this[privateProperty];
  }
}

const myObject = new MyClass();
console.log(myObject.getPrivate()); // 'private'
console.log(myObject[privateProperty]); // undefined

迭代器

Symbol.iterator 可以用来定义对象的迭代器方法,使得对象可以被 for...of 循环遍历。

const myObject = {
  name: 'Tom',
  age: 18,
  [Symbol.iterator]: function* () {
    for (const key in this) {
      if (this.hasOwnProperty(key)) {
        yield [key, this[key]];
      }
    }
  }
};

for (const [key, value] of myObject) {
  console.log(key, value);
}

模块化

在模块化开发中,可以使用 Symbol 来定义模块的命名空间,避免命名冲突。

const myModule = Symbol('myModule');

export default {
  [myModule]: true,
  foo() {
    console.log('foo');
  }
};

总结

Symbol 是 ES6 中新增的一种基本数据类型,可以作为对象属性的标识符,避免对象属性名冲突的问题。Symbol 还有一些常用的方法,如 Symbol.for() 和 Symbol.keyFor()。在前端开发中,Symbol 可以应用于私有属性、迭代器、模块化等场景。

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


纠错
反馈