JavaScript Symbol的用法

1. Symbol是什么

Symbol是ES6 引入了一种新的基本类型,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、boolean、string、number、object。

2. Symbol 语法

Symbol([description])   // description为Symbol的描述,不影响Symbol的唯一

3. Symbol的特点

  • 独一无二,Symbol('a')Symbol('a')是不相等的
  • 不能使用new关键字创建对象,new Symbol()是不合法的
  • Symbol值无法参与运算,无法隐式转成字符串,会报TypeError
  • 作为对象属性无法用.运算符,但是可以使用方括号[]
  • 作为对象属性,无法被循环遍历,如for...infor...of,也不会被Object.keysObject.getOwnPropertyNamesJSON.stringify返回
  • Object.getOwnPropertySymbols方法,可以获取对象的所有 Symbol 属性名
  • Reflect.ownKeys可以返回所有类型的键名,包括常规键名和 Symbol 键名

看下面的例子,加深印象:

const a = Symbol('a');
const b = Symbol('b');
a == b; // false
a + "Hello"; // TypeError: Cannot convert a Symbol value to a string
a.toString() + ""; // Ok,output: 'Symbol()'
const obj = { [a]: 1, [b]: 2, c: 3 };
Object.keys(obj); // ['c']
Object.getOwnPropertySymbols(obj); // [ Symbol(a), Symbol(a) ]
Reflect.ownKeys(obj); // [ 'c', Symbol(a), Symbol(a) ]
JSON.stringify(obj); // '{"c":3}'

const obj2 = { a }; 
obj2; // { a: Symbol(a) },Key为string,值为Symbol

4. Symbol的使用场景

模拟私有属性

由于Symbol作为对象属性时不参与遍历,而且无法使用字符串key值访问,所以可以模拟私有属性。

js内置对象中也大量使用Symbol,比如Symbol.iterator,访问对象的迭代器。或者Symbol.toPrimitive,将对象转成原始值。

在Symbol出现之前,人们经常使用__前缀来表示私有属性。

消除魔法字符串

假如我们有一个枚举:

const colors = {
	RED: 'red',
	GREEN: 'green',
	BLUE: 'blue'
};

我们用colors.RED表示红色,只要保证它的值和其他颜色的值不同即可,值是什么不重要,这时就可以用Symbol代替

const colors = {
	RED: Symbol(),
	GREEN: Symbol(),
	BLUE: Symbol()
};

防止属性名冲突

当你想向一个全局对象中添加属性时,你又不知道对象是否包含该属性,就容易覆盖。而使用Symbol作为对象属性可以避免这个问题,因为它的独一无二的。

const global_obj = { a: 1 }
global_obj['a'] = 2;  // 覆盖了
const a = Symbol('a');
global_obj[a] = 2;  // 不会覆盖,因为Symbol独一无二

你想扩展库的功能,又怕覆盖了它原来的代码,使用Symbol就非常合适。库的作者可能也怕我们乱改库的代码,所以一些重要的代码,比如私有方法,就直接使用Symbol定义了。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Symbol 常见用法如下: 1. 创建唯一的属性名 由于 Symbol 值是唯一的,因此可以用它来创建唯一的属性名,避免对象属性名冲突。例如: ```javascript const key = Symbol(); const obj = {}; obj[key] = 'value'; console.log(obj[key]); // 'value' ``` 2. 作为常量定义 由于 Symbol 值是唯一的且不可变,因此可以用它来定义常量。例如: ```javascript const RED = Symbol(); const GREEN = Symbol(); const BLUE = Symbol(); function getColor(color) { switch (color) { case RED: return 'red'; case GREEN: return 'green'; case BLUE: return 'blue'; } } console.log(getColor(GREEN)); // 'green' ``` 3. 作为私有属性 由于 Symbol 值不会被暴露在对象的属性列表中,因此可以用它来作为私有属性。例如: ```javascript const name = Symbol(); class Person { constructor(n) { this[name] = n; } getName() { return this[name]; } } const person = new Person('John'); console.log(person.getName()); // 'John' console.log(person[name]); // undefined ``` 4. 作为 Iterator 对象的键 由于 Symbol 值是唯一的,因此可以用它来作为 Iterator 对象的键。例如: ```javascript const myIterable = {}; myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; for (const value of myIterable) { console.log(value); } // Output: // 1 // 2 // 3 ``` 5. 作为内置 SymbolJavaScript 还提供了一些内置的 Symbol 值,如 Symbol.iterator、Symbol.toPrimitive、Symbol.toStringTag 等,可以用来定制对象的行为。例如: ```javascript const obj = { [Symbol.toPrimitive](hint) { if (hint === 'number') { return 42; } else if (hint === 'string') { return 'forty-two'; } else { return true; } } }; console.log(obj + 1); // 43 console.log(obj.toString()); // 'forty-two' console.log(String(obj)); // 'forty-two' console.log(Number(obj)); // 42 console.log(Boolean(obj)); // true ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值