Loading

TypeScript学习笔记(二)函数和类【面向对象】

一、函数的语法

1. 函数声明

ES5 中函数的写法:

function run() {
    console.log("run");
}
var run2= function() {
    console.log("run2");
}

TypeScript中主要的不同点是函数需要标明参数的类型和返回值类型。

函数声明方式:

function 函数名(参数类型 参数名): 返回值类型 {
  return 值;
}

匿名函数:

let 变量值 = function(参数类型 参数名): 返回值类型 {
  return 值;
}

例如:

function getInfo(name:string, age: number): string {
    return `${name}---${age}`
}

let getInfo2 = function(name:string, age: number): string {
    return `${name}---${age}`
}

2. 函数的可选参数

语法:在选填的参数后添加 ? 即可:

function getInfo(name:string, age?: number): string {
    if(age) {
        return `${name}---${age}`
    }
    else {
        return `${name}---年龄保密`
    }
}

当调用:

getInfo("mike")

运行结果:

image-20210808212316487

而当填入第二个参数时:

console.log(getInfo("mike", 15))

运行结果:

image-20210808212411517

tips: 可选参数必须配置在参数列表的最后面

3. 函数的默认参数

function getInfo(name:string, age: number=20): string {
    return `${name}---${age}`
}
console.log(getInfo("mike"))

运行结果:

image-20210808213057629

4. 函数的剩余参数

类似其他语言的可变参数:

function sum(...result: number[]):number {
    return result.reduce((preValue, item)=>preValue+item)
}
console.log("sum", sum(1,2,3,4));

运行结果:

image-20210808213843038

此外我们还可以取前面几个参数,然后后面的参数被分配到剩余参数中:

function sum(a: number, b: number,...result: number[]):number {
    console.log("first two number: ", a, b);
    return result.reduce((preValue, item)=>preValue+item)
}
console.log("sum", sum(1,2,3,4));

运行结果:

image-20210808214234327

5. 函数的重载

function fun(name: string): string;
function fun(age: number): string;
function fun(val: any): any {
    if(typeof str === 'string'){
        return 'string类型:'+val;
    }
    else {
        return '我的年龄是:'+val;
    }
}

调用:

console.log(fun("Hello world"));
console.log(fun(18));

运行结果;

image-20210808215241949

二、JavaScript中的类(ES5)

1. 在构造函数中定义成员变量和方法

function Person() {
  this.name = '张三';
  this.age = 15;
}

使用 new 关键字创建一个对象并打印:

var person = new Person();
console.log(person);
image-20210808220139764

添加成员方法:

function Person() {
  this.name = '张三';
  this.age = 15;
  this.run = function() {
    console.log(this.name + '在奔跑');
  }
}

调用:

person.run();

2. 在原型链中定义变量和方法

Person.prototype.sex = "男";
Person.prototype.work = function() {
  console.log(this.name + "在工作");
}
var p = new Person();
p.work();

运行结果:

image-20210808220744009

原型链上面的属性会被多个实例共享,而构造函数中的不会。

3. 静态方法

Person.getInfo = function() {
  console.log("我是静态方法")
}

调用方式:

Person.getInfo();

4. 类的继承

使用原型链+对象冒充的组合继承模式

  • 对象冒充方式:
function Student() {
  Person.call(this);// 对象冒充实现继承,可以继承构造函数中定义的成员
}
let student = new Student();
student.run();

但这样无法继承原型链中定义的属性和方法。

  • 原型链方式:
function Student() {
}
Student.prototype = new Person();
let student = new Student();
student.work();// 调用原型链中添加的方法

这种方式既可以继承构造函数中定义的成员,也可以继承原型链中定义的成员。

存在的问题:实例化子类的时候没法给父类传参

  • 组合继承模式:
function Student(name, age) {
  Person.call(this, name, age); // 1.对象冒充
}
Student.prototype = new Person(); // 2.原型链
let student = new Student("李四", 18);
student.work();// 调用原型链中添加的方法

三、 TypeScript中的类

1. 类的定义

class Person {
    name: string; // 属性
    constructor(n:string) {
        this.name = n;
    }
    run(): void {
        console.log(this.name + "在奔跑");
    }
}
var person = new Person("张三");
person.run();

可以看到,类的定义和 JavaC++ 等语言基本相同,非常人性化。

2. 类的方法

class Person {
    ...
    getName():string {
        return this.name;
    }
    setName(name:string):void {
        this.name = name;
    }
}

3. 继承的实现

使用 extends 关键字:

class Student extends Person {
    constructor(name:string) {
        super(name);
    }
}
var student = new Student("李四");
student.run();

不得不说,这才是真正的 ”Java“Script吧?和 Java 代码相似度99%。

方法的重写(即Java中的Override):

class Student extends Person {
  constructor(name:string) {
    super(name);
  }
  // 重写的方法
  run(): void {
    console.log(this.name + "在奔跑(学生)");
  }
}
var student = new Student("李四");
student.run();
image-20210808224234824

4. 类中的修饰符

  • public
  • protected
  • private

作用与 C++ Java 等中的作用一致。

tips:属性如果不添加修饰符,默认是 public

5. 静态属性和静态方法

class Person {
 // ...
 // 静态属性
 protected static personNum:number = 0;
 constructor(n:string) {
   this.name = n;
   Person.personNum++;
 }
 // ...
 // 静态方法
 static printPersonNum():void {
   console.log(Person.personNum);
 }
}

示例:

var p1 = new Person("张三");
var p2 = new Person("李四");
var p3 = new Person("王五");
Person.printPersonNum();

6. 抽象类的定义

语法:

abstract class 类名{
	abstract 抽象方法名(): 返回值类型 {
    ...
  }
  ...
}

7. 接口的定义

属性接口

语法

interface 接口名 {
    接口中包含的属性...
}

示例:

// 属性接口
interface FullName {
    firstName: string;
    lastName: string;
}
// 使用
function printName(fullName: FullName) {
    console.log(`${fullName.firstName}--${fullName.lastName}`);
}
let obj = {
    age: 15,
    firstName: "mike",
    lastName: "smith"
}
printName(obj);

即约束了传入的对象必须包含接口所规定的参数。

运行结果:

image-20210808233809960

接口的可选属性

语法和可选参数相同,既是在变量名后面加上 ?

interface FullName {
    firstName: string;
    lastName?: string;
}

使用接口语法模拟封装ajax请求的参数对象:

interface Config {
    type: string;
    url: string;
    data?: string;
    dataType: string;
}
function ajax(config: Config) {
    var xhr = new XMLHttpRequest();
    xhr.open(config.type, config.url, true);
    xhr.send(config.data);
    xhr.onreadystatechange = ()=>{
        if(xhr.readyState==4 && xhr.status == 200){
            console.log("成功");
        }
    }
}

可见使用接口可以很方便地使IDE为我们提供输入参数的类型提示,与 JavaScript 中需要翻看文档形成鲜明的对比。

函数类型接口

interface encrypt {
    (key:string, val:string) : string;
}
var md5:encrypt = function(key:string, value:string) {
    return "使用md5加密后的字符串";
}
var sha1:encrypt = function(key:string, value:string) {
    return "使用sha1加密后的字符串";
}

可索引接口

对数组的约束

interface nameArr {
    [index: number]:string
}
let nameList: nameArr = ["mike","Jack","Sam"];

对对象的约束

interface strMap {
    [index: string]:string;
}
var map:strMap = {
    "mike": "123@qq.com",
    "Jack": "456@qq.com"
}

类类型接口

Java 的接口比较类似,TypeScript 的接口多了属性约束,并使用 implements 关键字来实现接口:

interface Animal {
    name: string;
    eat(food:string):void;
}
class Dog implements Animal {
    name: string;
    constructor(name:string) {
        this.name = name;
    }
    eat(food: string): void {
        console.log(`小狗${this.name}吃${food}`)
    }
}

8. 接口的继承

interface Workable extends Animal {
    work():void;
}
posted @ 2021-08-09 00:15  CodeReaper  阅读(127)  评论(0编辑  收藏  举报