typescript入门笔记自用2(类&函数)


简单的例子:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter(“world”);

继承
类当然会有继承功能,使用关键字extends进行继承,下面是一个简单的例子
class Son extends Greeter {
hello() :string {
return “hello”
}
}
let son = new Son(‘son’)
console.log(son.hello());
console.log(son.greet());

上面的例子里,Son类不包含构造函数,但当子类(超类)有构造函数时,必须在构造函数内调用super,它会调用基类的构造函数。而且,在构造函数内访问this之前,必须调用super。
class Animal {
name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(${this.name} moved ${distanceInMeters}m.);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log(“Slithering…”);
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 45) {
console.log(“Galloping…”);
super.move(distanceInMeters);
}
}
let sam = new Snake(“Sammy the Python”);
let tom: Animal = new Horse(“Tommy the Palomino”);
sam.move();
tom.move(34);

public, private, protected
默认情况下为public
private的意思就是私有化,使得变量只能在当前这个类中访问。在子类中,虽然仍能super构造方法,但无论是在子类的其他方法里,还是直接访问,都访问不到
class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(${this.name} moved ${distanceInMeters}m.);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log(“Slithering…”);
super.move(distanceInMeters);
}
log() {
console.log(this.name); //name为私有属性,只能在"animal"类中访问
}
}

protected
protected与private类似,不同的是protected在派生类中仍可以访问,在实例中也是不可访问的
class Animal {
protected name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(${this.name} moved ${distanceInMeters}m.);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log(“Slithering…”);
super.move(distanceInMeters);
}
log() {
console.log(this.name); //success
}
}
let sam = new Snake(“Sammy the Python”);
console.log(sam.name);// name是受保护的,只能在类"Animal"中及其子类访问

readonly 和 参数属性
参数属性就是方便直接进行初始化,感觉还是写出来比较好,不过要看得懂别人的用法,贴个官网例子
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor (theName: string) {
this.name = theName;
}
}
let dad = new Octopus(“Man with the 8 strong legs”);
dad.name = “Man with the 3-piece suit”; // 错误! name 是只读的.

//参数属性
class Octopus {
readonly numberOfLegs: number = 8;
constructor(readonly name: string) {
}
}

存取器
属性的get和set方法,注意一点,当属性有get方法而没有set方法时自动转变为readonly,使用这个版本输出要调到ECMAScript5或更高
let passcode = “secret passcode”;
class Employee {
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
if (passcode && passcode == “secret passcode”) {
this._fullName = newName;
}
else {
console.log(“Error: Unauthorized update of employee!”);
}
}
}
let employee = new Employee();
employee.fullName = “Bob Smith”;
if (employee.fullName) {
alert(employee.fullName);
}

抽象类
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log('Department name: ’ + this.name);
}
abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
constructor() {
super(‘Accounting and Auditing’); // 在派生类的构造函数中必须调用 super()
}
printMeeting(): void {
console.log(‘The Accounting Department meets each Monday at 10am.’);
}
generateReports(): void {
console.log(‘Generating accounting reports…’);
}
}
let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在

把类当作接口使用
class Point {
x: number = 1;
y: number = 2;
}
interface pointPlus extends Point {
z: string
}

函数
先来看一个完整函数类型的例子
let myFunc: (x: number, y: number) => number =
function(x: number, y: number) {
return x + y
}

类型推论
赋值语句一边指定了类型,另一边就会自动推断出类型
let myFunc: (x: number, y: number) => number =
function(x, y) {
return x + y
}

可选参数和默认参数
一个是加?,一个是指定默认值,两者的共同作用就是让参数可选,二者的类型推论相同。
使用默认参数时,要传递undefind作为参数,表示使用默认值。
function buildName(firstName = “Will”, lastName: string) {
return firstName + " " + lastName;
}
let result1 = buildName(“Bob”); // error, too few parameters
let result2 = buildName(“Bob”, “Adams”, “Sr.”); // error, too many parameters
let result3 = buildName(“Bob”, “Adams”); // okay and returns “Bob Adams”
let result4 = buildName(undefined, “Adams”); // okay and returns “Will Adams”

剩余参数
剩余参数可以有多个,也可以没有,我们创建一个数组存放,前面用…省略号,类似拓展运算符
function buildName(firstName: string, …restOfName: string[]): string {
return firstName + " " + restOfName.join(" ")
}
let res = buildName(“chen”, “zhi”, “cong”, “sb”)
console.log(res);

this与箭头函数
我们知道,js在函数调用时才会指定this(非箭头函数),对于下面一个例子,this指向了window,所以会报错
let deck = {
suits: [“hearts”, “spades”, “clubs”, “diamonds”],
cards: Array(52),
createCardPicker: function() {
return function() {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);

        return {suit: this.suits[pickedSuit], card: pickedCard % 13}; //error
    }
}

}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);

解决这个问题,可以用箭头函数,它会保留上下文this
let deck = {
suits: [“hearts”, “spades”, “clubs”, “diamonds”],
cards: Array(52),
createCardPicker: function() {
// NOTE: the line below is now an arrow function, allowing us to capture ‘this’ right here
return () => {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);

        return {suit: this.suits[pickedSuit], card: pickedCard % 13};
    }
}

}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);
但是现在this.suits[pickedSuit]的类型仍然为any,也就是ts没有对它进行类型推论,解决这一问题我们需要显式指出this,在下面的例子中,this被显式指定为Deck接口类型的
interface Card {
suit: string;
card: number;
}
interface Deck {
suits: string[];
cards: number[];
createCardPicker(this: Deck): () => Card;
}
let deck: Deck = {
suits: [“hearts”, “spades”, “clubs”, “diamonds”],
cards: Array(52),
// NOTE: The function now explicitly specifies that its callee must be of type Deck
createCardPicker: function(this: Deck) {
return () => {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);

        return {suit: this.suits[pickedSuit], card: pickedCard % 13};
    }
}

}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

函数重载
需求:根据传入参数的不同,返回不同类型的结果。在js中,我们无需做额外的操作,需要返什么返回什么即可,但在ts中,我们利用函数重载
let suits = [“hearts”, “spades”, “clubs”, “diamonds”];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x: any): any {
// Check to see if we’re working with an object/array
// if so, they gave us the deck and we’ll pick the card
if (typeof x == “object”) {
let pickedCard = Math.floor(Math.random() * x.length);
return pickedCard;
}
// Otherwise just let them pick the card
else if (typeof x == “number”) {
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
let myDeck = [{ suit: “diamonds”, card: 2 }, { suit: “spades”, card: 10 }, { suit: “hearts”, card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieChan_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值