TS 3.1

原文地址 www.tslang.cn

自 ECMAScript 2015 起,symbol成为了一种新的原生类型,就像numberstring一样。

symbol类型的值是通过Symbol构造函数创建的。

let sym1 = Symbol();

let sym2 = Symbol("key"); // 可选的字符串key

Symbols 是不可改变且唯一的。

let sym2 = Symbol("key");
let sym3 = Symbol("key");

sym2 === sym3; // false, symbols是唯一的

像字符串一样,symbols 也可以被用做对象属性的键。

注释:这里有个以变量名为键的 ES6 语法

let sym = Symbol();

let obj = {
    [sym]: "value"
};

console.log(obj[sym]); // "value"

Symbols 也可以与计算出的属性名声明相结合来声明对象的属性和类成员。

const getClassNameSymbol = Symbol();

class C {
    [getClassNameSymbol](){
       return "C";
    }
}

let c = new C();
let className = c[getClassNameSymbol](); // "C"

众所周知的Symbols

除了用户定义的 symbols,还有一些已经众所周知的内置 symbols。 内置 symbols 用来表示语言内部的行为。

以下为这些 symbols 的列表:

Symbol.toStringTag

方法,被内置方法Object.prototype.toString调用。返回创建对象时默认的字符串描述。

Symbol.hasInstance

方法,会被instanceof运算符调用。构造器对象用来识别一个对象是否是其实例。

例子:

class Array1 {
  static [Symbol.hasInstance](instance) {
    return Array.isArray(instance);
  }
}

console.log([] instanceof Array1);

Symbol.toPrimitive

方法,被ToPrimitive抽象操作调用。把对象转换为相应的原始值。

例子:

const object1 = {
  [Symbol.toPrimitive](hint) { // hint 应该是原始值的类型
    if (hint === 'number') {
      return 42;
    }
    return null;
  }
};

console.log(+object1);
// expected output: 42

Symbol.species

函数值,为一个构造函数。用来创建派生对象。

注释:在 TS 中对于 map 的方法类型不够准确。如下例a.map在未定义 Symbol.species 时,返回的是 Array1 的子类,具有 dosome 这个方法
例子:

class Array1 extends Array {
  static get [Symbol.species]() { return Array; }
  dosome(){}
}

const a = new Array1(4);
const mapped = a.map(x => x * x); // Symbol.species 方法默认返回的类型是 this,在该例中即 Array1 本身

console.log(a instanceof Array1); // true

console.log(mapped instanceof Array1); // false 

console.log(mapped instanceof Array); // true

Symbol.isConcatSpreadable

布尔值,表示当在一个对象上调用Array.prototype.concat时,这个对象的数组元素是否可展开。

例子:

const alpha = ['a', 'b', 'c'];
const numeric = [1, 2, 3];
let alphaNumeric = alpha.concat(numeric);

console.log(alphaNumeric);
// expected output: Array ["a", "b", "c", 1, 2, 3]

numeric[Symbol.isConcatSpreadable] = false;
alphaNumeric = alpha.concat(numeric);

console.log(alphaNumeric);
// expected output: Array ["a", "b", "c", Array [1, 2, 3]]

Symbol.iterator

方法,被for-of语句调用。返回对象的默认迭代器。

例子:必须是赋予一个迭代器,不然会有奇怪的报错

var myIterable = {}
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
[...myIterable] // [1, 2, 3]

Symbol.match

方法,被String.prototype.match调用。正则表达式用来匹配字符串。

例子:

'string'.match(regexp)
// 等同于
regexp[Symbol.match]('string')

class MyMatcher {
  [Symbol.match](string) {
    return 'hello world'.indexOf(string);
  }
}

'e'.match(new MyMatcher()) // 1

Symbol.replace

方法,被String.prototype.replace调用。正则表达式用来替换字符串中匹配的子串。

例子:

class Replace1 {
  constructor(value) {
    this.value = value;
  }
  [Symbol.replace](string) {
    return `s/${string}/${this.value}/g`;
  }
}

console.log('foo'.replace(new Replace1('bar')));

Symbol.search

方法,被String.prototype.search调用。正则表达式返回被匹配部分在字符串中的索引。

Symbol.split

方法,被String.prototype.split调用。正则表达式来用分割字符串。

Symbol.unscopables

对象,它自己拥有的属性会被with作用域排除在外。

with 语句不被推荐使用

原文地址:https://www.cnblogs.com/qq3279338858/p/14241389.html