ES6中的Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。

重要的干货提前说:当使用JSON.stringify()将对象转换成JSON字符串的时候,Symbol属性也会被排除在输出内容之外,所以JSON.parse(JSON.stringify(oldObj))不能拷贝含有Symbol属性的对象。另一文:JSON.parse拷贝的局限性

它是 JavaScript 语言的第七种数据类型,前六种是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)

这样写是会报错的:
let a = new Symbol()

Uncaught TypeError: Symbol is not a constructor
注意:Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。
所以,我们只要将Symbol当成唯一的字符串就行
正确写法: let s
= Symbol(); typeof s // "symbol"

1,概要:

  1,每一个Symbol都不相等

// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();

s1 === s2 // false

  2,Symbol能接受一个参数,注意数只是表示对当前 Symbol 值的描述,相同参数的Symbol值也都是不相同的

    参数可以为所有类型,如果 Symbol 的参数是一个对象,就会调用该对象的toString方法

  3,注意:Symbol 值不能与其他类型的值进行运算,但是,Symbol 值可以显式转为字符串,另外,Symbol 值也可以转为布尔值,但是不能转为数值。

    

let sym = Symbol('My symbol');
String(sym) // 'Symbol(My symbol)'

let sym = Symbol();
Boolean(sym) // true

Number(sym) // TypeError

"your symbol is " + sym
// TypeError: can't convert symbol to string

2,Symbol.prototype.description

let sym = Symbol('hello')
sym //Symbol(hello)
sym.description //"hello"

3,作为属性名时的遍历

Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回。

但是,它也不是私有属性,有一个Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。

const obj = {};
let a = Symbol('a');
let b = Symbol('b');

obj[a] = 'Hello';
obj[b] = 'World';
for (let i in obj) {
  console.log(i); // 无输出
}
const objectSymbols = Object.getOwnPropertySymbols(obj); objectSymbols // [Symbol(a), Symbol(b)]

另一个新的 API,Reflect.ownKeys()方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。

let obj = {
  [Symbol('my_key')]: 1,
  enum: 2,
  nonEnum: 3
};

Reflect.ownKeys(obj)
//  ["enum", "nonEnum", Symbol(my_key)]

4,Symbol.for(),Symbol.keyFor() 

Symbol.for()Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');
s1 === s2 // true

Symbol.for("bar") === Symbol.for("bar")
// true
Symbol("bar") === Symbol("bar")
// false


Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key。
let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"

let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined

Symbol.for()的这个全局登记特性,可以用在不同的 iframe 或 service worker 中取到同一个值。

iframe = document.createElement('iframe');
iframe.src = String(window.location);
document.body.appendChild(iframe);

iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo')
// true

 

原文地址:https://www.cnblogs.com/hsmWorld/p/12802489.html