【TS篇三】类、函数、for-of循环、类型推断

news/2024/5/20 1:18:00 标签: , 函数, for-of循环, 类型推断, ts

文章目录

    • 一、
      • 1.1 基本示例
      • 1.2 继承
      • 1.3 实例成员访问修饰符
        • 1.3.1 `public` 开放的
        • 1.3.2 `private` 私有的
        • 1.3.3 `protected` 受保护的
        • 1.3.4 `readonly` 只读的
        • 1.3.5 在参数中使用修饰符
      • 1.4 属性的存(get)取(set)器
      • 1.5 静态成员
    • 二、函数
    • 三、for-of 循环
    • 四、型推断(Type Inference)
    • 五、模块
      • 5.1 概念
      • 5.2 模块通信:导出
      • 5.3 模块通信:导入

一、

1.1 基本示例

class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    sayHello() {
        console.log(this.name);
    }
}

let zs: Person = new Person('张三', 18);

1.2 继承

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

这个例子展示了最基本的继承:从基中继承了属性和方法。 这里, Dog是一个 派生,它派生自 Animal ,通过 extends关键字。 派生通常被称作 ,基通常被称作

因为 Dog继承了 Animal的功能,因此我们可以创建一个 Dog的实例,它能够 bark()move()

下面是一个更复杂的例子:

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);

与前一个例子的不同点是,派生包含了一个构造函数,它 必须调用 super(),它会执行基的构造函数。 而且,在构造函数里访问 this的属性之前,我们 一定要调用 super()。 这个是TypeScript强制执行的一条重要规则。

这个例子演示了如何在子里可以重写父的方法。 SnakeHorse都创建了 move方法,它们重写了从Animal继承来的 move方法,使得 move方法根据不同的而具有不同的功能。 注意,即使 tom被声明为Animal型,但因为它的值是 Horse,调用 tom.move(34)时,它会调用 Horse里重写的方法:

Slithering...
Sammy the Python moved 5m.
Galloping...
Tommy the Palomino moved 34m.

1.3 实例成员访问修饰符

1.3.1 public 开放的
  • 默认为 public
class Animal {
    public name: string;
    public constructor(theName: string) { this.name = theName; }
    public move(distanceInMeters: number) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}
1.3.2 private 私有的
  • 不能被外部访问,只能在的内部访问使用
  • 私有成员不会被继承
class Person {
  public name: string;
  public age: number = 18;
  private type: string = 'human'
  public constructor (name, age) {
    this.name = name
    this.age = age
  }
}
1.3.3 protected 受保护的
  • private 似,但是可以被继承
class Person {
    protected name: string;
    constructor(name: string) { this.name = name; }
}

class Employee extends Person {
    private department: string;

    constructor(name: string, department: string) {
        super(name)
        this.department = department;
    }

    public getElevatorPitch() {
        return `Hello, my name is ${this.name} and I work in ${this.department}.`;
    }
}

let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); // 错误

注意,我们不能在 Person外使用 name,但是我们仍然可以通过 Employee的实例方法访问,因为Employee是由 Person派生而来的。

1.3.4 readonly 只读的
1.3.5 在参数中使用修饰符

在上面的例子中,我们不得不定义一个受保护的成员 name和一个构造函数参数 theNamePerson里,并且立刻给 nametheName赋值。 这种情况经常会遇到。 参数属性可以方便地让我们在一个地方定义并初始化一个成员。

class Person {
  	name: string;
  	age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
}

可以简写为:

class Person {
    constructor(public name: string, public age: number) {
    }
}

tset_187">1.4 属性的存(get)取(set)器

let passcode = "secret passcode";

class Employee {
  	// 私有成员,外部无法访问
    private _fullName: string;

  	// 当访问 实例.fullName 的时候会调用 get 方法
    get fullName(): string {
        return this._fullName;
    }

  	// 当对 实例.fullName = xxx 赋值的时候会调用 set 方法
    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);
}

1.5 静态成员

  • 不需要实例化访问的成员称之为静态成员,即只能被访问的成员
  • static 关键字
class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        let xDist = (point.x - Grid.origin.x);
        let yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

let grid1 = new Grid(1.0);  // 1x scale
let grid2 = new Grid(5.0);  // 5x scale

console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

二、函数

2.1 函数参数

  • 参数及返回值
function add(x: number, y: number): number {
    return x + y
}
  • 可选参数
function add(x: number, y?: number): number {
    return x + 10
}
  • 默认参数
function add(x: number, y: number = 20): number {
    return x + y
}
  • 剩余参数
function sum(...args: number[]): number {
    let ret: number = 0
    args.forEach((item: number): void => {
        ret += item
    })
    return ret
}

sum(1, 2, 3)

2.2 箭头函数

  • 基本示例
let add = (x: number, y: number): number => x + y

三、for-of 循环

  • for 循环
  • forEach
    • 不支持 break
  • for in
    • 会把数组当作对象来遍历
  • for of
    • 支持 break

四、型推断(Type Inference)

TypeScript 编译器会根据一些简单的规则来推断你定义的变量的

​ 当你没有标明变量的型时,编译器会将变量的初始值作为该变量的

let num = 3
//此时我未标注 num 变量的型 ,初始值为数字型 , 变量num为数字型
let str = 'string'
//此时我未标注 str 变量的型 ,初始值为字符串型 , 变量str为字符串

当然,型推断不仅仅发生在简单数据型上面,复杂数据型上依然可以被TypeScript编译器进行推断

let arr = ['one','two','three']
//此时未标注 arr 数组中的每个元素型 , 初始值为字符串,则相当于:
//let arr : string[]

//但如果数组中没有元素,为空数组,则型为 never

let obj = {a:1,b:2}
//此时未标注对象内的数据型,默认为初始值,为数字型
//let obj : {a:number,b:number}

//不仅如此,ts编译器还会推断函数的返回值型
const fun = (a:number,b:number) =>{
    retrun a + b;
}
//const fun =(a:number,b:numer) => number

但在使用函数返回值型推断时,在编写函数内部的代码就失去了函数返回值型检测功能,使用函数返回值的型需要明确的指定

​ 正常情况下,TypeScirpt编译器时可以推断出变量型的,开发者不需要编写型注释,但在TypeScirpt编译器不能正常推断型时,开发者需要编写型注释

  • 第一种情况:
    如果一个变量被声明后,没用被立即初始化,那么编译器将不能正确推断出它的型,将被赋予any

    let anything 
    //此时变量未被及时初始化,编译器默认它为any型:let anything :any
    
    
  • 第二种情况:
    当被调用的函数的返回值为any型的时候,应该使用型注释来声明它的

    let json ='{"name":"张三"}';
    let person = JSON.parse(json);
    //let json:string
    //let person:any => let person:{name:string}
    
    
  • 第三种情况:
    ​ 当变量有可能有多个型时:

    let num = [-10,-1,20]
    //target => bollean|number
    let target =false
    
    for(let i=0;i<num.length;i++){
        if(num[i]>0){
            //不能将number型分配给bollean型
            target = num[i];
        }
    }
    
    
  • 第四种情况:
    函数的参数必须标注型,TypeScript并不能推断函数参数的

五、模块

5.1 概念

5.2 模块通信:导出

export default xxx

export const foo: string = 'bar';
export const bar: string = 'foo';

5.3 模块通信:导入

// 加载默认成员
import xxx from '模块标识'

// 按需加载模块成员
import {foo, bar} from '模块'

http://www.niftyadmin.cn/n/5148251.html

相关文章

【Excel密码】四个方法,设置excel表格只读模式

Excel文件想要设置成只读模式&#xff0c;其实很简单&#xff0c;今天给大家分享四个excel设置只读模式的方法。 方法一&#xff1a;文件属性 右键点击文件&#xff0c;查看文件属性&#xff0c;在属性界面&#xff0c;勾选上只读属性就可以了。 方法二&#xff1a;始终以只读…

队列、循环队列和双端队列

目录 1、队列 1.1 概念 2.2 队列的使用 2.3 队列模拟实现 2、循环队列 2.1 循环队列的认识 2.2 设计循环队列 3. 双端队列 (Deque) 1、队列 1.1 概念 队列 &#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列…

大数据毕业设计选题推荐-自媒体舆情分析平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

JavaSE java对象的比较

目录 1 问题提出2 元素的比较2.1 基本类型的比较2.2 对象的比较 3 对象的比较3.1 覆写基类的equal3.2 基于Comparble接口类的比较3.3 基于比较器比较3.4 三种方式对比 4 集合框架中PriorityQueue的比较方式5 总结 1 问题提出 上节课我们讲了优先级队列&#xff0c;优先级队列在…

数据库的增删查改(一)

Mysql的基本操作 一. 新增1.单行数据全列插入 2.多行数据指定列插入二.查询1.全列查询2.指定列查询3.查询字段为表达式4.别名5.去重6.排序7.条件查询 一. 新增 1.单行数据全列插入 表示在SQL语句中一行一行插入. 2.多行数据指定列插入 二.查询 1.全列查询 全列查询就是将val…

子串简写(第14届蓝桥杯b组题目)

程序猿圈子里正在流行一种很新的简写方法&#xff1a; 对于一个字符串&#xff0c;只保留首尾字符&#xff0c;将首尾字符之间的所有字符用这部分的长度代替。 例如 internationalization 简写成 i18n&#xff0c;Kubernetes 简写成 K8s&#xff0c;Lanqiao 简写成 L5o 等。 …

js实现下载pdf而不是直接浏览器打开

fileLinkToStreamDownload(url, fileName, type) {const that this;let reg /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]).)([A-Za-z0-9-~\/])$/;if (!reg.test(url)) {throw new Error("传入参数不合法,不是标准的文件链接");} else {let x…

CentOS 7上创建Python 3虚拟环境

在CentOS 7上创建Python 3虚拟环境可以使用virtualenv包。以下是创建Python 3虚拟环境的步骤&#xff1a; 确保已经安装了Python 3和pip。可以通过在终端中运行以下命令来检查它们是否已安装&#xff1a; python3 --version pip3 --version如果未安装&#xff0c;请使用以下…