TypeScript中的函數(shù)和類你了解嗎
函數(shù)
以下聲明了一個函數(shù)類型,通過type來定義類型別名,void 表示沒有返回值
type fnType = () => void;
作為參數(shù)
函數(shù)可以作為參數(shù),傳遞到另一個函數(shù)中
type fnType = () => void;
function foo(fn: fnType) {
fn();
}
function bar() {
console.log("bar");
}
foo(bar); // bar
與js代碼不同的點在于傳入的參數(shù)需要定義類型注解
定義函數(shù)
定義函數(shù)的時候,需要給入?yún)⒅付愋妥⒔?,返回值如果可以自行推?dǎo)出來,也可以不寫,如 add 和 minus 函數(shù),但是作為參數(shù)時,是必須要寫的,如 calc 函數(shù)中的入?yún)?fn
function add(num1: number, num2: number): number {
return num1 + num2;
}
function minus(num1: number, num2: number): number {
return num1 - num2;
}
function calc(
num1: number,
num2: number,
fn: (num1: number, num2: number) => void
) {
console.log(fn(num1, num2));
}
calc(30, 20, add); // 50
calc(30, 20, minus); // 10
函數(shù)參數(shù)的類型
ts中函數(shù)會規(guī)定參數(shù)的類型和個數(shù),當(dāng)個數(shù)不確定時,可以使用可選類型、剩余參數(shù)、默認值
可選類型
可選類型相當(dāng)于該定義的類型和undefined的聯(lián)合類型,所以參數(shù)有三種選擇、傳入該類型、不傳或者undefined
function foo(x: number, y?: number) {
console.log(x, y);
}
foo(1, 2); // 1 2
foo(3); // 3 undefined
foo(4, undefined); // 4 undefined
參數(shù)默認值
參數(shù)設(shè)置了默認值就使之稱為了可選類型,不過有默認值的參數(shù)最好放在必傳參數(shù)后面
function baz(x: number = 20, y: number) {
console.log(x, y);
}
baz(10, 20); // 10 20
baz(undefined, 20); // 20 20
剩余參數(shù)
剩余參數(shù)要放在必傳參數(shù)之后
function sum(num: number, ...args: number[]) {
console.log(num, args);
}
sum(10); // 10 []
sum(10, 20); // 10 [20]
sum(10, 20, 30); // 10 [20, 30]
this的默認推導(dǎo)
在對象的方法中定義的this,ts是可以自動推導(dǎo)的,但是獨立函數(shù)中的this,是推導(dǎo)不出來的。

必須要在獨立函數(shù)中定義this的類型
type ThisType = { name: string };
const eating = function (this: ThisType) {
console.log(this.name + " eating~");
};
const person = {
name: "kiki",
eating,
};
person.eating()
函數(shù)重載
函數(shù)重載指的是函數(shù)名相同,參數(shù)個數(shù)或者類型不同,所定義的多個處理方法。
比如需要對字符串拼接或者數(shù)字求和操作,雖然我們知道 + 號可以用在字符串和數(shù)字上,但是在類型檢測嚴格的ts代碼中,這樣寫編譯是不通過的,需要使用【類型縮小】,縮小類型的判斷,再進行處理。

通過聯(lián)合類型,參數(shù)組合的可能性越多,需要越多的if語句來進行判斷,并且函數(shù)的返回值類型也是未知的,在這種情況下可以使用【函數(shù)重載】
在ts中,定義函數(shù)名和參數(shù)類型的重載函數(shù),再通過實現(xiàn)函數(shù)來定義具體實現(xiàn)。 會根據(jù)數(shù)據(jù)類型在重載函數(shù)中調(diào)用,再執(zhí)行實現(xiàn)函數(shù)的代碼。
function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: any, y: any) {
return x + y;
}
console.log(add(1, 2));
console.log(add("a", "b"));
如果傳遞的參數(shù)與重載函數(shù)中定義參數(shù)不同,是無法通過編譯的。

類
初始化
類中定義的變量需要初始化,可以在定義類的時候就賦值或者通過constructor來操作
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
const person = new Person("alice", 20);
繼承
ts和js中一致,都是通過 extends 實現(xiàn)繼承,使用父級參數(shù)和方法時使用 super 關(guān)鍵字。
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class Student extends Person {
sno: number;
constructor(name: string, age: number, sno: number) {
super(name, age);
this.sno = sno;
}
}
const student = new Student("alice", 20, 1);
多態(tài)
使用多態(tài)可以寫出更加具備通用性的代碼,如果想要實現(xiàn)多態(tài)首先得有繼承,并且父類引用指向子類對象。
class Animal {
action() {
console.log("animal action");
}
}
class Dog extends Animal {
action() {
console.log("dog running");
}
}
class Fish extends Animal {
action() {
console.log("fish swimming");
}
}
function doAction(animals: Animal[]) {
animals.forEach((animal) => {
animal.action();
});
}
doAction([new Dog()]);
doAction([new Dog(), new Fish()]);
doAction([new Dog(), new Fish(), new Animal()]);
這里相當(dāng)于 const animal1: Animal = new Dog() ,看起來是 Animal 對象,其實是 Dog 對象,這里的父類引用指向的是子類對象,所以最后執(zhí)行的是 Dog 對象的方法

成員修飾符
成員修飾符有以下三種
- public 表示共有的,任何地方都可見,當(dāng)沒有定義成員修飾符時,默認為public
- private 私有的,只有類中能夠訪問到
- protected 被保護的,表示類自身和子類可以訪問到
public
class Person {
public username: string = "alice";
getName() {
return this.username;
}
}
const person = new Person();
console.log(person.username);
private
通過private修飾的變量,在實例對象上也是不可訪問的。

protected
通過protected修飾的變量,在實例對象上也是不可訪問的。

readonly
readonly表示該屬性只讀,初始化了之后就不能以任何方式修改,無論是在類內(nèi)部,還是修改實例對象,但當(dāng)它是一個對象時,只要不改變它的內(nèi)存地址,修改對象的屬性是可以的。

訪問器
訪問器給私有屬性提供get/set方法,讓我們在類外部獲取/修改私有屬性
class Person {
private _name: string;
constructor(newName: string) {
this._name = newName;
}
get name() {
return this._name;
}
set name(newName) {
if (newName) this._name = newName;
}
}
const person = new Person("alice");
console.log(person.name);
person.name = "kiki";
console.log(person.name);
person.name = "";
console.log(person.name);
通過get/set屬性來修改私有屬性可以做到攔截/判斷的作用

靜態(tài)成員
靜態(tài)成員通過 static 關(guān)鍵字來定義,通過 static 定義的屬性,是定義在類自身的,只能通過自己訪問,在類內(nèi)部和實例對象都是無法訪問到的。

抽象類
在定義很多通用的調(diào)用接口時,我們通常會讓調(diào)用者傳入父類,通過多態(tài)來實現(xiàn)更加靈活的調(diào)用方式。
但是,父類本身可能并不需要對某些方法進行具體的實現(xiàn),所以父類中定義的方法, 我們可以定義為抽象方法。
abstract class Shape {
abstract getArea(): void;
}
class Circle extends Shape {
private radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
getArea() {
return this.radius * this.radius * 3.14;
}
}
class Rectangle extends Shape {
private width: number;
private height: number;
constructor(width: number, height: number) {
super();
this.width = width;
this.height = height;
}
getArea() {
return this.width * this.height;
}
}
function calcArea(shape: Shape) {
return shape.getArea();
}
console.log(calcArea(new Circle(3)));
console.log(calcArea(new Rectangle(2, 6)));
抽象方法和方法通過 abstract 來修飾,并且抽象類定義時有兩條規(guī)則:
- 抽象方法必須要在子類實現(xiàn)
- 抽象類是不能被實例化的

類的類型
類本身也是可以作為一種數(shù)據(jù)類型的,可以用作類型注解。
class Person {
name: string = "alice";
eating() {}
}
const person: Person = {
name: "kiki",
eating() {
console.log("i am eating");
},
};
function printPerson(person: Person) {
console.log(person.name);
}
printPerson(new Person());
printPerson(person);
printPerson({ name: "macsu", eating() {} });
只要符合類的格式,就可以使用類的類型
函數(shù)和類在JS和TS中都是至關(guān)重要的,可以幫助開發(fā)者更好規(guī)范開發(fā)時的代碼,減少線上故障~
總結(jié)
以上就是關(guān)于TypeScript函數(shù)和類的內(nèi)容,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
js阻止默認事件與js阻止事件冒泡示例分享 js阻止冒泡事件
嵌套的div元素,如果父級和子元素都綁定了一些事件,那么在點擊最內(nèi)層子元素時可能會觸發(fā)父級元素的事件,下面介紹一下js阻止默認事件與js阻止事件冒泡示例,大家參考使用吧2014-01-01
使用原生JS獲取select元素選中的value和text值
這篇文章介紹了使用原生JS獲取select元素選中的value和text值,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03
「中高級前端面試」JavaScript手寫代碼無敵秘籍(推薦)
這篇文章主要介紹了JavaScript手寫代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

