Symbol是什么?
是es6出现的一种新的原始数据类型,可以从根本上防止属性名的冲突。
Symbol有什么用处?
- 由于每一个
Symbol
值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。
比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),这个时候就可以用到Symbol了。 - 由于以 Symbol 值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法
如何使用Symbol?
`let mySymbol = Symbol();
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
注意: 在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。
属性名的遍历
Symbol 作为属性名,该属性不会出现在for...in
、for...of
循环中,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols
方法,可以获取指定对象的所有 Symbol 属性名。
Object.getOwnPropertySymbols
方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
另一个新的 API,Reflect.ownKeys
方法可以返回所有类型的键名,包括常规键名和Symbol 键名。
Symbol for Vs Symbol
Symbol.for()
与Symbol()
这两种写法,都会生成新的 Symbol。
它们的区别是,前者会被登记在全局环境中供搜索, 后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值.
这里的全局环境是指:Symbol.for为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。
网友评论