📅  最后修改于: 2023-12-03 14:57:25.135000             🧑  作者: Mango
符号类型(Symbol)是 TypeScript 中引入的一种新的基础数据类型,主要用于定义唯一的对象属性名。Symbol 值是通过Symbol构造函数创建的,它可以接受一个字符串作为参数,表示创建的 Symbol 的描述信息。
符号类型的主要作用是用于属性名的定义,它可以更好地保证对象属性的唯一性,避免属性名冲突的问题。
在 TypeScript 中,我们可以使用符号类型作为对象的属性名。例如:
// 定义符号类型
const name = Symbol('name');
// 定义对象
const person = {
[name]: 'Tom'
};
console.log(person[name]); // 输出:Tom
console.log(person['name']); // 输出:undefined
从上面的例子中可以看到,我们使用符号类型作为对象的属性名,可以更加灵活地定义对象的属性,避免名称冲突的问题。
除了上面的基本使用方式,符号类型还有以下一些特性:
当我们使用 Symbol 构造函数创建符号类型时,每次创建都会返回一个唯一的 Symbol 值,即使创建时传入的描述是相同的。例如:
console.log(Symbol('name') === Symbol('name')); // 输出:false
因此,我们可以通过符号类型来保证对象属性的唯一性。
除了我们自己创建的符号类型,TypeScript 还提供了一些 well-known symbols(内置符号类型),例如 Symbol.iterator、Symbol.toStringTag 等。这些符号类型的作用是为 JavaScript 内置对象提供一些默认行为或定义额外的属性。例如:
// 默认使用 Symbol.iterator 迭代
const arr = [1, 2, 3];
for (const item of arr) {
console.log(item);
}
// 打印对象时自动调用 Symbol.toStringTag
const obj = { a: 1, b: 2 };
console.log(obj); // 输出:[object Object]
obj[Symbol.toStringTag] = 'MyObject';
console.log(obj); // 输出:[object MyObject]
Symbol.hasInstance 是用于定义对象的 instanceof 运算符行为的内置符号类型。我们可以通过重写一个对象的 Symbol.hasInstance 方法来自定义 instanceof 运算符的行为。例如:
class MyArray {
static [Symbol.hasInstance](instance: any) {
return Array.isArray(instance);
}
}
console.log([] instanceof MyArray); // 输出:true
console.log({} instanceof MyArray); // 输出:false
Symbol.species 也是一个内置的符号类型,用于定义在派生类中使用的构造函数,在许多 ES6 内置类型上都有这个属性(例如 Array,Map 等)。例如:
class MyArray extends Array {
static get [Symbol.species]() {
return Array;
}
}
const myArray = new MyArray(1, 2, 3);
const newArray = myArray.map(item => item * 2);
console.log(myArray instanceof MyArray); // 输出:true
console.log(newArray instanceof MyArray); // 输出:false
console.log(newArray instanceof Array); // 输出:true
console.log(newArray); // 输出:[2, 4, 6]
以上就是 TypeScript 中符号类型的介绍。符号类型的引入使得 TypeScript 在属性名的定义上更加灵活,避免了属性名冲突的问题。同时,内置的 Symbol 也为我们提供了一些方便的扩展功能和自定义行为的接口。