ES6 Symbol类型

Symbol符号:符号的用途确保对象属性使用唯一标识符,创建唯一记号,进而用作非字符串形式的对象属性。
(1)基本用法:Symbol需要依靠Symbol()函数初始化,在调用Symbol()函数时,可以传入一个字符串参数作为对符号的描述。
    let sym = Symbol('my symbol');
但即使字符串参数相同,它们也并不相等,因为我们之前提到符号用途是唯一标识一个对象属性,字符串参数只是对符号的一个描述
    let sym1 = Symbol('foo');
    let sym2 = Symbol('foo');
    console.log(sym1 == sym2); // false
符号不能与new一同使用,否则会报错TypeError:Symbol is not a constructor
(2)如果运行时,不同部分希望共享一个符号实例,需要用一个字符串作为键,在全局符号表注册并重用符号。此时需要Symbol.for()方法
    let sym1 = Symbol.for("sym1");
    let sym1_repeat = Symbol.for("sym1");
    console.log(sym1, sym1_repeat, sym1 == sym1_repeat); // Symbol(sym1) Symbol(sym1) true
第一次调用Symbol.for时,它会检查全局符号注册表,发现不存在相应符号,则生成一个新符号实例添加到注册表中,第二次调用Symbol.for,
且字符串键相同时,则返回全局符号注册表中已注册的符号实例。
(3)Symbol.keyFor(符号):在全局符号注册表中查询符号,查询到则返回符号的字符串键,否则返回undefined
    let sym = Symbol.for("key");
    console.log(Symbol.keyFor(sym)); // key
(4)使用符号作为属性:
    let sym = Symbol('foo');
    console.log(sym.toString()); // Symbol(foo)
    let obj = {
      [Symbol('bar')]: 'can not direct search',
      sym: 'can direct search'
    };
    console.log(obj["[Symbol('bar')]"]); // 报错,不指定一个变量名指向对符号的引用,而直接将符号作为对象属性,无法直接获取
    console.log(obj['sym']); // can direct search,指定sym变量名,指向Symbol('foo')
    // 如果不指定对符号的引用,那么就无法直接利用obj[xxx]获取符号,必须像以下代码循环遍历,才能获取到
    let barSymbol = Object.getOwnPropertySymbols(obj).find((symbol) => symbol.toString().match(/bar/));
    console.log(barSymbol);

 (5)获取对象中符号属性的方法:

  getOwnPropertySymbols():它会返回一个数组,里面存储着对象的符号属性

  我们可以联想到 getOwnPropertyNames():它会返回一个数组,里面存储这对象的非符号属性

  getOwnPropertyDescriptors():返回一个对象,里面存储常规属性以及符号属性

  Reflect.ownKeys():返回一个数组,里面存储着常规属性和符号属性的键

 (6)Symbol 常用内置符号:内置符号会暴露一些方法处理时的内部行为,而我们可以利用这一点对其内部行为进行修改或重写,从而达到我们自己想要的目的。

  我们平时用到的 for-of 语句就用到了 Symbol.iterator 符号属性,它的值为一个方法,这个方法返回对象的默认迭代器,由 for-of 语句使用

举个简单的例子:我们平时用 for-of 语句对数组迭代时,其实本质上是调用数组的 Symbol.iterator 属性,即一个返回默认迭代器的方法.

let arr = [1, 2, 3, 4, 5];
for (let i of arr[Symbol.iterator]()) {
  console.log(i);
} // 1 2 3 4 5

 

posted @ 2021-11-05 15:01  TwinkleG  Views(32)  Comments(0)    收藏  举报