今天来了解在 TypeScript 中使用 Class,Class Member 包含了: Fields 、 Readonly、Constructors、Method、Getters / Setters、Index Signatures。
实例属性: 在ES6中, 是无法直接在class中定义属性,必须定义在 constructor里面并使用this.
,而 ES7这可以直接在calss中定义, 而 TypeSript 也跟上脚步,可以直接在class里面去定义属性,且public公用的。
readonly : 可以使用 readonly 关键字来唯读属性, 防止进行赋值。
class Point {
x: number; //可以使用实例属性
y: number;
readonly name: string = "show point"; //readonly唯读
constructor(x = 0, y = 0) { //预设给0
this.x = x;
this.y = y;
}
printPoint() {
console.log(`x: ${this.x}, y: ${this.y}`);
}
}
let p = new Point(2, 4);
p.printPoint(); //x: 2, y: 4
p.name = "hihi"; //若对readonly属性赋值会报错 error: Cannot assign to 'name' because it is a read-only property.
--strictPropertyInitialization
(tsconfig.json) : class实例属性的赋值检查。如下面例子,已宣告name属性型别,却没给予赋值, 就会报错提醒。class GoodGreeter {
name: string; //error: Property 'name' has no initializer and is not definitely assigned in the
word: string;
constructor() {
this.word = "hello";
}
}
constructors: 他跟function的使用很像, 你可以使用型别注记,预设参数。但官网提到可以 overloads, 内心一个问号,javascript class 只有一个 constructor, 所以 TS 可以多个吗?
//原文: Class constructors are very similar to functions. You can add parameters with type annotations, default values, and overloads
class Point2 {
x: number;
y: number;
// Normal signature with defaults
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
}
let p2 = new Point2(100,200);
class Point {
// Overloads
constructor(x: number, y: string);
constructor(s: string);
constructor(xs: any, y?: any) {
// TBD
}
}
後来实做发现,是不行的唷,不能使用 multiple constructor, 是无法overloads的, 我在想他应该想讲的是method可以overloads, 一个函式提供多个型别定义。
class Point3 {
// Overloads
constructor(x: number, y: string){ //errro: Multiple constructor implementations are not allowed.
this.x = x;
this.y = y;
};
constructor(s: string){
this.s = x;
}
}
let p3 = new Point3(1,"5");
let p4 = new Point3("helllo")
console.log(p3); //Point3 { x: 1, y: '5' }
console.log(p4); //Point3 { x: 'helllo', y: undefined }
super: 在 JavaScript 我们有时候会忘记在 this
之前使用 super
去调用父层,但在 TypeScript 我们忘了使用 super
, complier就会提醒我们。
class Base {
k = 4;
}
class Derived extends Base {
constructor() {
console.log(this.k);
// 'super' must be called before accessing 'this' in the constructor of a derived class.
super();
}
}
这跟 JavaScript 一样,可增加 class 方法,并定义参数型别。此外,在 method 里要使用 class 的属性,需要使用 this
关键字。
let z: number = 0;
class Point4 {
x = 10;
y = 10;
z: string = "hello";
//method
scale(n: number): void {
this.x *= n;
this.y *= n;
}
//修改class的z属性,需使用this.z,不然视为修改class外的 z
editZ(){
z = "world"; //error: Type 'string' is not assignable to type 'number'.
}
}
class 也有存取器(accessors), 就是getter 及 setter,用以改变属性的读取和赋值行为,与 es6 class 一样。 另外在TS4.3引入了新特性, set 及 set 传入的参数型别可以多种型别。
class Thing {
_size = 0;
get size(): number {
return this._size;
}
set size(value: string | number | boolean) {
let num = Number(value);
// Don't allow NaN, Infinity, etc
if (!Number.isFinite(num)) {
this._size = 0;
return;
}
this._size = num;
}
}
let thing = new Thing();
console.log(thing.size); //0
thing.size = "seven";
console.log(thing.size); //0
thing.size = 2.2;
console.log(thing.size); //2.2
在JavaScript中使用[]
来操作object属性,那些属性JavaScript 都会要 toString
去读取, 如下方例子, 使用obj["name0"]
没问题,使用obj[name1]
则会报错。
let obj = {
name0: "iris",
name1: "iris",
2: "iris"
};
console.log(obj["name0"]); //iris
console.log(obj[2]); //iris
console.log(obj[name1]); //error: name1 is not defined
在 TypeScript 中 , 会强制提醒使用 toString,减少我们的错误。
TypeScript 的Index Signatures 必须是 string 或者 number。
let obj2 = {
toString() {
console.log('toString called');
return 'Hello';
}
};
class Foo {
constructor(public message: string) {}
log() {
console.log(this.message);
}
}
let foo: any = {};
foo['Hello'].log(); // World
foo[obj2] = new Foo('World'); //error: Type '{ toString(): string; }' cannot be used as an index type.
想了解更多 Index Signatures 相关可参考 Day16这篇 。
感谢阅读!明天见~
https://www.typescriptlang.org/docs/handbook/2/classes.html
https://willh.gitbook.io/typescript-tutorial/advanced/class#typescript-zhong-lei-bie-de-yong-fa
<<: Day24 用python写UI-聊聊Text(一)
串流处理的应用场景近年来越来越常见,尤其是IOT产业的蓬勃发展,加上硬体技术的发展,越来越多的即时资...
在 Vue.js 有的生命周期在 Livewire 中也都有,除此之外在 Livewire 中各自变...
Hi 我是 Tomaz. 第一次参加铁人赛,和各位铁人一起进行磨练,希望撑得过去 ? 认真学 Co...
目的 了解 forEach() 的来由。 说明 简单来说,实作任意资料结构的 forEach(),最...
grep grep(Global search a Regular Expression and P...