您的位置:首页 > 文旅 > 旅游 > javascript中symbol使用场景及使用方法

javascript中symbol使用场景及使用方法

2024/12/23 11:03:26 来源:https://blog.csdn.net/misstianyun/article/details/142303804  浏览:    关键词:javascript中symbol使用场景及使用方法

Symbol 是 JavaScript ES6 引入的一种新数据类型,表示独一无二的值。它是 JavaScript 的基本类型之一(除了 StringNumberBooleanNullUndefinedObject 之外)。Symbol 值是唯一的,即使两个 Symbol 具有相同的描述,它们的值也是不同的。Symbol 的主要用处是创建对象的唯一属性名,以避免属性名冲突,特别是在大型项目或库中非常有用。

1. Symbol 的基本使用

const sym1 = Symbol('description');
const sym2 = Symbol('description');console.log(sym1 === sym2); // false

即使 sym1sym2 都有相同的描述('description'),它们依然是不同的值。

2. Symbol 作为对象的属性键

在 JavaScript 对象中,通常属性名是字符串。但有时可能会有两个不同的模块使用相同的属性名,导致冲突。Symbol 可以用作对象的唯一属性键,避免这种冲突。

const sym = Symbol('myKey');
const obj = {[sym]: 'value associated with symbol'
};console.log(obj[sym]); // "value associated with symbol"
console.log(obj['myKey']); // undefined
  • 这里的 sym 是唯一的,即使有其他对象也用类似的描述 'myKey',它们也不会冲突。

3. 隐藏属性

因为 Symbol 属性不会出现在常规的对象属性遍历操作中(如 for...inObject.keys()),它可以用来定义一些“隐藏”的或“内部”的属性,防止外部不小心修改。

const sym = Symbol('hiddenProperty');
const obj = {[sym]: 'secret',normalProp: 'visible'
};console.log(Object.keys(obj)); // ["normalProp"]
console.log(Object.getOwnPropertyNames(obj)); // ["normalProp"]
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(hiddenProperty)]

虽然 Symbol 属性不会被 Object.keysObject.getOwnPropertyNames 枚举到,但可以通过 Object.getOwnPropertySymbols() 获取它们。

4. 全局 Symbol

有时你可能希望在不同模块或文件中共享同一个 Symbol,这时可以使用 Symbol.for() 方法。它在全局 Symbol 注册表中查找并返回一个符号,如果该符号不存在则会创建它。

const sym1 = Symbol.for('sharedSymbol');
const sym2 = Symbol.for('sharedSymbol');console.log(sym1 === sym2); // true
  • Symbol.for() 不同于 Symbol(),前者会检查全局 Symbol 注册表,而后者每次都会创建一个新的 Symbol。

此外,可以使用 Symbol.keyFor() 来获取全局 Symbol 的键:

const sym = Symbol.for('sharedSymbol');
console.log(Symbol.keyFor(sym)); // "sharedSymbol"

5. 常见场景

5.1 避免对象属性名称冲突

在一些大型项目中,不同的模块或第三方库可能会向同一个对象添加属性,如果属性名冲突,可能会覆盖或破坏彼此的逻辑。通过 Symbol,我们可以确保每个属性都是唯一的。

const library1 = {[Symbol('id')]: 123
};const library2 = {[Symbol('id')]: 456
};console.log(library1[Symbol('id')]); // undefined (无法通过其他 Symbol 访问)
5.2 模拟私有属性

虽然 JavaScript 没有真正的私有属性,但可以使用 Symbol 来实现类似于“私有”的属性,因为它们不会出现在常规的属性枚举中。

const createPerson = () => {const age = Symbol('age');return {setAge(value) {this[age] = value;},getAge() {return this[age];}};
};const person = createPerson();
person.setAge(30);
console.log(person.getAge()); // 30
  • 通过 Symbol,可以模拟出一个不易被外部访问或修改的“私有”属性。
5.3 迭代器 (Iterators)

Symbol.iterator 是内置的 Symbol,它允许对象自定义迭代行为。可以通过为对象定义 Symbol.iterator,使其可以被 for...of 循环迭代。

const myIterable = {[Symbol.iterator]: function* () {yield 1;yield 2;yield 3;}
};for (let value of myIterable) {console.log(value); // 1, 2, 3
}
  • Symbol.iterator 是 ES6 引入的,用于使对象成为可迭代的。
5.4 元编程

Symbol 还可以用作元编程的一部分,通过覆盖语言内部行为。以下是一些内置的 Symbol,用于修改对象的默认行为:

  • Symbol.iterator:用于定义对象的默认迭代器。
  • Symbol.toStringTag:用于自定义 Object.prototype.toString 返回的内容。
  • Symbol.hasInstance:自定义 instanceof 操作符的行为。
class MyClass {static [Symbol.hasInstance](instance) {return typeof instance === 'string';}
}console.log('hello' instanceof MyClass); // true
  • 在上面的例子中,MyClass 自定义了 instanceof 的行为,使其返回 true 只要对象是一个字符串。

6. 总结

  • Symbol 是一种创建独一无二值的数据类型,通常用于避免属性名冲突。
  • Symbol 常用于对象的属性键,尤其是在库或框架中,用来定义不会被意外覆盖的“隐藏”属性。
  • Symbol.forSymbol.keyFor 允许在全局共享 Symbol
  • 通过 Symbol,可以模拟私有属性,并通过内置的 Symbol 修改对象的内置行为,如 Symbol.iteratorSymbol.toStringTag 等。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com