文章目录
前端Symbol介绍及其常见用法
Symbol是ES6中新增的一种基本数据类型,它表示独一无二的值。在前端开发中,Symbol具有多种用途,可以用于创建唯一对象属性名、定义对象的迭代行为、自定义instanceof行为等。本文将详细介绍Symbol函数的常见用法。
一、Symbol函数的创建
Symbol函数的基本语法是
Symbol([description])
,其中
description
是一个可选的字符串参数,用于描述这个Symbol值的信息,便于调试和理解。需要注意的是,创建Symbol值时不能使用
new
关键字,否则会抛出TypeError错误。
let s1 =Symbol();let s2 =Symbol("description");
console.log(s1);// Symbol()
console.log(s2);// Symbol(description)
通过Symbol函数创建的每个Symbol实例都是唯一的,即使使用相同的描述信息,它们之间也是不相等的。
let s1 =Symbol("foo");let s2 =Symbol("foo");
console.log(s1 === s2);// false
二、Symbol的常见用法
- 创建唯一对象属性名
在对象中,我们通常使用字符串或数字作为属性名,但这可能导致意外的命名冲突。Symbol的独特性使其成为创建唯一属性的绝佳选择。
const id =Symbol('id');const user ={
name:"Alice",[id]:123// 使用Symbol作为属性名};
在这个例子中,即使有另一个属性名为
id
,它也不会和
Symbol('id')
冲突。这样可以保护一些私有属性,不被外部轻易访问和修改。
- 定义对象的迭代行为
Symbol.iterator是一个预定义好的Symbol值,表示对象的默认迭代器方法。通过定义Symbol.iterator属性,可以自定义一个对象的迭代行为。
const myObject ={
items:[1,2,3],[Symbol.iterator]:function*(){for(let item ofthis.items){yield item;}}};for(let item of myObject){
console.log(item);// 输出 1, 2, 3}
- 自定义instanceof行为
Symbol.hasInstance是一个预定义好的Symbol值,用于定义对象的instanceof操作符行为。通过定义Symbol.hasInstance方法,可以自定义一个对象的instanceof行为。
classFoo{static[Symbol.hasInstance](obj){return obj instanceofArray;}}
console.log([]instanceofFoo);// true
console.log({}instanceofFoo);// false
- 防止魔法字符串带来的问题
在一些条件判断中,使用字符串容易引入魔法字符串的问题。通过Symbol可以定义常量,避免使用魔法字符串,让代码更易维护。
const actionTypes ={CREATE:Symbol('CREATE'),UPDATE:Symbol('UPDATE'),DELETE:Symbol('DELETE')};functionhandleAction(action){switch(action){case actionTypes.CREATE:
console.log("创建操作");break;case actionTypes.UPDATE:
console.log("更新操作");break;case actionTypes.DELETE:
console.log("删除操作");break;}}handleAction(actionTypes.CREATE);// 输出: 创建操作
- 使用Symbol.for和Symbol.keyFor
Symbol.for()方法会根据给定的字符串key返回一个已经存在的symbol值。如果不存在,则会创建一个新的Symbol值并将其注册到全局Symbol注册表中。而Symbol.keyFor()方法会返回一个已经存在的Symbol值的key,如果给定的Symbol值不存在于全局Symbol注册表中,则返回undefined。
const symbol1 = Symbol.for('foo');const symbol2 = Symbol.for('foo');
console.log(symbol1 === symbol2);// trueconst key1 = Symbol.keyFor(symbol1);
console.log(key1);// 'foo'const symbol3 =Symbol('bar');const key2 = Symbol.keyFor(symbol3);
console.log(key2);// undefined
三、Symbol的注意事项
- Symbol类型值需通过Object.getOwnPropertySymbols()获取
Symbol创建的值是不可枚举的,以下方式遍历对象的结果都不会包含Symbol内容:
for...in
循环:会遍历对象的可枚举属性,但会忽略不可枚举的属性。Object.keys()
:返回一个数组,其中包含对象的所有可枚举属性的名称,不可枚举的属性不会被包含在返回的数组中。JSON.stringify()
:只会序列化对象的可枚举属性,而不会包含不可枚举属性。
可以使用
Object.getOwnPropertySymbols()
方法来获取指定对象的所有Symbol属性名。
- Symbol在JSON.stringify中的问题
JSON.stringify转换和Symbol相关的数据时,会忽略掉Symbol类型的key或value。
const obj ={[Symbol('foo')]:'bar'};
console.log(JSON.stringify(obj));// {}
版权归原作者 TechFrontRunner 所有, 如有侵权,请联系我们删除。