TypeScript笔记---kalrry
1. 简介
ts是由微软开发的一个自由开源的编程语言。 他是js的一个超集 本质上ts扩展了js的语法 解决了js上的很多痛点 弱类型 很难模块化 没有类的概念
1.ts是js的超集
2.他对js进行了扩展 加入了很多新的特性
3.ts代码需要通过一个编译器来进行编译 编译成为js 才能运行
4.ts完全兼容js 任何代码都可以在ts中直接写
5.ts的语法更加的严格 ts是在代码编译的时候就能发现问题 减少了出错的几率
2. 开发环境
1.电脑上必须有node
2.全局安装typescript
npm install --save typescript
3.查看版本
tsc -v
4.要写typescript 那么我们在创建文件的时候 要创建一个ts后缀的文件
5.使用ts编译器编译成js
1.cd到指定路径下
2.使用tsc 文件名即可编译
2.1. 通过配置文件的方式进行运
上面的写法在每次修改完ts之后 我们都要重新再次编译 很麻烦 所以我们能不能让文件修改完成之后自动的进行编译
1.cd到指定路径下
2.使用tsc -init 初始化一个tsconfig.json的配置文件(用于指定编译的配置项)
3.直接输入tsc 即可
2.2. 自动编译
需要监听这个tsconfig.json
2.2.1. vscode自动编译
1.点击终端 运行任务
2.在下拉的弹出框中选择typescript
3.在弹出的下拉框中选择 监视 tsconfig.json 即可完成自动编译
2.2.2. 命令方式自动编译
在编译文件的时候 使用-w命令 ts编译器就会自动监听数据的变化 从而重新编译当前文件
tsc -w
3. Ts知识点
3.1. 变量/常量
注意: let 创建的变量不能重复声明
注意: let const创建的变量是块级作用域
注意:创建变量的时候 除了下划线_和美元$付浩源 不能包含其他的特殊字符 包括空格
3.2. 类型声明
在ts中有一个非常重要的特点就是类型声明 类型声明所指的就是在创建ts的变量的时候我们需要指定当前变量的数据类型是什么 指定好类型之后ts编译器就会检查我们设置的值 是否符合当前指定的类型 不符合就会报错
语法:
let 变量名:数据类型=“值”
3.3. 数据类型
在ts中支持所有传统的js数据类型
string 字符串
number 数字
boolean 布尔值
// 创建变量
let text:string="我是一个字符串"
let bool:boolean=true
object 对象
array 数组
// 创建对象
let obj:object={
name:"xixi",
age:18
}
// 创建数组
let arr:number[]=[1111,22222,33333];
let arrb:Array<string>=["你好","你坏"]
3.4. ts新增的数据类型
any类型 在一些情况下 如果我们无法确定你当前这个变量存储的数据类型是什么 那么这个时候我们可以把数据类型设置成any(任意类型)
注意:如果我们把数据类型设置成了any 那么ts编译器就会在解析当前变量的时候 跳过类型验证
// 任意类型
let num:any="什么数据类型都可以存储"
tuple元祖类型 就是已知长度和数据类型的数组
// 元祖
let arrc:[string,number,boolean]=["你好",11,true]
enum 枚举类型 枚举就是给一组数值赋予友好的名字,枚举也可以理解为是一组命名元素的集合给一组数值起个友好的名字
// enum枚举
// enum 名字{数值1,数值2,。。。。。n}
// enum user{xiaoming,xiaohong,xiaobai}
// console.log(user.xiaobai)
// 设置枚举类型的值 设置了数字的值之后 只会影响自身以及后面的内容
// enum user{xiaoming,xiaohong=99,xiaobai}
// console.log(user.xiaoming)
// 给枚举类型设置类字符串类型的值之后 那么他后面的所有值都必须初始化
// 因为后面的值 没有办法给字符串自增1
enum user{xiaoming,xiaohong="你好",xiaobai="设置初始值"}
console.log(user.xiaoming)
void 没有返回值
// void没有返回值
// 函数如果有返回值 那么建议设置返回值类型
function fun():string{
return "xxx"
}
// 函数如果没有返回值
function funb():void{
console.log("没有返回值")
}
never 表示永远不会出现的类型
3.5. 类型别名
类型别名 就是给数据类型起一个友好的名字 使用type关键字来进行类型别名的创建
// 类型别名
type xx=string
let namedemo:xx="xixix"
因为上面的类型别名在开发的时候单独使用的场景很少 通常类型别名都是要配合联合类型 来一起使用的
3.6. 联合类型
联合类型就表示一个变量如果要存储多个数据类型的时候 传统定义方式是不行的 因为传统的方式当我们指定一个数据类型之后 就没有办法在给当前这个变量设置其他类型了
// 联合类型
type newType=string|number|boolean
let age:newType=true
3.7. 自动类型判断
ts中拥有自动的类型判断机制 党对变量进行声明和赋值的时候 ts的编译器会自动判断变量的类型并且赋值 (是在我们没有指定数据类型的基础之上才会自动类型判断)
4. 面向对象
面向对象 OOP思想 程序之中所有的操作都是以对象的方式来完成的
举例:
操纵浏览器 使用window对象
操纵网页 使用document对象
操纵控制台 使用console对象
一切操纵都要通过对象 这也就是面向对象
程序是什么?
计算机程序的本质就是对象现实事物的抽象 抽象的反义词就是具体 比如 照片就是对具体的一个物体进行抽象 汽车模型就是对汽车进行抽象 程序也就是对事物进行抽象 通过程序 我们可以标识一个人一个事物等等 一个事物就是一个对象
在程序中所有的对象都被分为两个部分 数据 与 功能 以人举例 人的姓名 年龄 性别 等都属于数据 人可以说话 走路等都属于功能 数据就是属性 功能就是方法
4.1. 类
操纵对象 创建对象 首先究竟要拥有对象
定义类对象:
class 类名{
属性名:数据类型;
constructor(参数:数据类型){
this.属性名=参数
}
方法(){
}
}
例子:
class User{
// 创建属性
name:string;
age:Number;
constructor(newname:string,newage:number){
this.name=newname
this.age=newage
}
showname(){
console.log("你好我是"+this.name)
}
}
// 使用类new关键字 可以方便的生产出一个实例对象 这个成产的过程叫实例化
let user= new User("xixi",18)
user.showname()
4.2. 面向对象的特点
4.2.1. 封装
封装:对象的本质上就是属性和方法的容器 主要的作用就是用来容纳属性和方法 这就是封装
默认情况下 对象的属性可以在任何地方进行修改
class User{
// 创建属性
name:string;
age:Number;
constructor(newname:string,newage:number){
this.name=newname
this.age=newage
}
showname(){
console.log("你好我是"+this.name)
}
}
// 使用类new关键字 可以方便的生产出一个实例对象 这个成产的过程叫实例化
let user= new User("xixi",18)
user.showname()
// 对象的属性可以在任何地方进行修改
console.log(user.age)
user.age=666
console.log(user.age)
但是但是 为了确保数据的安全性 在ts中 可以对属性的权限进行设置
1. 三种修饰符
1.public(默认值) 公开的 谁都可以使用 可以在类 子类 对象中进行修改(就算我们没有写public 程序运行的时候也会默认给我们补上)
// public 共有的 任何地方都可以使用修改
class a{
public name:string="你好"
}
let demoa=new a()
console.log(demoa.name)
demoa.name="xixi"
console.log(demoa.name)
2.protected 受保护的 只能在当前类和子类中使用
// protected受保护的
class a{
protected name:string="你好"
showname(){
console.log(this.name)
}
}
let demoa=new a()
// 读取
// console.log(demoa.name)//因为name是受保护的 所以不能在类外部使用
demoa.showname()
3.private 私有的 只能在当前类中使用
// private 私有的
class a{
private name:string="你好"
private showname(){
console.log(this.name)
}
}
let demoa=new a()
// 读取
console.log(demoa.name)//因为name是私有的 不能在类外部使用
demoa.showname()//因为showname是私有的 不能在类外部使用
2. 只读属性
readonly 属性生成之后不能修改
3. 静态属性
static 使用静态属性修饰的内容 不需要实例化就可以直接使用
// static 就可以不用实例化直接使用
class a{
static namedemo:String="xixi"
}
console.log(a.namedemo)
4.2.2. 继承
继承是面向对象中另一个重要的特性 通过继承可以讲别的类中的属性和方法放置到当前类中
// 继承
// 父类
class Fu{
public name:String="我是父类的属性111"
public showName(){
console.log("我是父类的方法")
}
}
// 子类 实现继承 extends关键字来实现继承
class Zi extends Fu{
// 既然子类继承了父类 那么就可以在子类中直接使用父类的属性和方法
zifun(){
console.log("我是子类我直接使用父类的内容"+this.name)
}
}
let zi=new Zi()
zi.zifun()
4.2.3. 多态/重写
多态的前提是 必须在继承的时候才能实现多态
在发生继承的时候 如果子类中的方法替换了父类中的同名方法 那么这个就叫做多态/重写
// 多态
// 父类
class Fu{
fufun(){
console.log("我是父类的方法")
}
}
// 子类 多态的前提是有继承
class Zi extends Fu{
// 多态就是子类中的方法和父类中的方法名相同的时候
// 那么子类的方法就会替换原有相同的那个内容
fufun(): void {
console.log("我是子类的方法")
}
}
let zi=new Zi()
zi.fufun()
5. 接口 interface
接口就是定义规范的一个技术 他主要定义行为和动作 是一个限制性的规范作用
通过接口可以对类中的属性进行格式上的规定
// 接口 接口名首字母大写 建议大家 在定义接口的时候 使用大写I作为开头
interface IUser{
name:String,//属性
age:number,
showname():void//方法
}
// 使用: 约束对象中的数据类型
let obj:IUser={
name:"你好",
age:18,
showname(){
console.log("你好呀")
}
}
// 大家会发现我们接口定义了3条数据 那么默认在使用的时候 就必须把这3条都要创建出来
我就是在创建接口的时候创建了多条 但是我只想使用其中一部分怎们办?
5.1. 可选属性
可选属性的含义就是该属性可以定义但是不使用 有的时候不需要完全匹配一个接口 那么就可以使用可选属性 使用?号来进行表示
interface IUser{
name?:String,//属性
age?:number,
showname():void//方法不行
}
let obj:IUser={
name:"xixi",
showname(){
console.log("不乖")
}
}
6. 泛型
定义函数或者类的时候 有些情况下 我们没有办法第一时间知道当前数据的数据类型(返回值 参数)这个时候泛型就派上了作用
泛型就是在定义函数接口或者类的时候 我们不先预定指定类型 而是在使用的时候在指定类型的一个特性
// 原来使用数据 都要先定义类型
// class Demo{
// name:String
// constructor(newname:string){
// this.name=newname
// }
// }
// 如果我们不确定这个数据的类型 那么我们可以使用泛型先创建 在使用的时候在注入数据类型
class Demo<T>{
name:T
constructor(newname:T){
this.name=newname
}
}