ts梳理

一、关于ts的安装和检验

1:安装ts前,必须先安装node.js
2:安装ts npm i typescript -g 全局安装
3:检验是否安装成功: tsc -v 若是显示版本便是安装成功

二、创建编译.ts文件,自动保存的配置

1:ts文件后面的后缀名为.ts 
**注意点:ts代码被tsc转化后施直接生成一个.js文件,然后直接操作js文件即可(引入和操作等)**
2:ts需要转化为js文件,在导入html文件中才能使用==这导入的方式是:在文件中新建一个终端,然后输入tsc 文件名称.ts后缀==

以下更为合适:创建编译.ts文件,自动保存的配置
//在项目的终端,输入tsc --init 来创建ts工具的文件夹 tsconfig.json
//然后在tsconfig.json文件夹里面修改  "outDir": "./js", 编译完就保存在这个js文件夹里面
然后在终端-运行任务-typescript-tsc监视 ---点击之后,会生成一个js文件夹,里面包含.js文件

三、typescript的基础

(1):ts的数据类型

ts数据类型
1:ts语法规定:在声明遍历的时候,必须指定数据类型
语法 — let 变量名:数据类型
let age:number
let myName:string = “pink”
作用:这样声明数据类型,使得声明的变量只能存储这样的类型数据
2:ts的数据类型有:string number boolean array tuple(枚举) any(任意类型) null underfined void类型 never类型
注意点:underfined和null的是其他类型的子类,所以这两个变量的值可以赋给其他类型的变量

//1:boolean类型
let flag: boolean = true;

//2;number类型
let num: number = 123;
// num = "pin"; //出错
console.log(num);//123

//3:定义数组
let arr: number[] = [1, 3, 5, 7];
let arr2: string[] = ["pink", "lala", "pa"];
console.log(arr2);//["pink", "lala", "pa"]
//第二种方式
let arr3: Array = [1, 4, 7]

//4:元祖类型 (tuple) 也是数组中的一种 可以指定多种类型
let arr0: [string, number, boolean] = ["pom", 123, true]

//5 枚举类型 (enmu) 
//可以定义flag 1为true -1为false  或者支付类型等 0未支付 1支付 2交易成功
enum Flag { success = 1, error = -1 }
let f: Flag = Flag.success;
console.log(f);//1
enum pay_status { nopay = 0, pay = 1, success = 2 };
let type: pay_status = pay_status.pay;
console.log(type);//1
enum Color { red, blur = 5, orange };
let x: Color = Color.orange;
console.log(x);//6

//6任意类型
let num2: any = 123;
num2 = "str";
console.log(num2);//str
//任意类型的作用:  需求对box盒子的文字改为红色
let oBox: any = document.querySelector(".box");
oBox.style.color = "red" //因为oBox是对象类型,但是ts中没有对象类型,因此使用any比较合适

//7: null (空) undefined (未定义) never(其他) 数据类型的子类型
let num: number | undefined;
// num = 123;
console.log(num);//123  //undefined 若是只定义为赋值的时候,输出undefined

//8:void类型---typescript中的void是表示没有任何类型,一般用于定义方法中方法没有返回值
function fun(): void {
  console.log("run");
}
fun();
//如果有返回值的时候,就需要在函数后面添加数据类型
function fun1(): number {
  return 123
}
fun1();

//9:其他类型,(包含null和undefined)的子类型,代表从不会出现的值。意味着声明never类型只能被never类型赋值,很少用
let b: null;
b = null;
let b3: undefined;
b3 = undefined;

(2):typescript的函数

//函数
//1:声明式函数
function fun(): string {
  return "pin";
}
fun();

//2:匿名函数
let fun2 = function (): number {
  return 123;
}
console.log(fun2());

//3:ts中定义方法传参
function getInfo(name: string, age: number): string {
  return `${name}---的年龄为---${age}岁`;
}
console.log(getInfo("lala", 18));
//注意点:name和age定义了传入的参数必须是字符串,数字型,返回值的类型为string
let getInfo2 = function (name: string, age: number): string {
  return `${name}---的年龄为---${age}`;
}
console.log(getInfo2("pon", 30));

function fun0(): void {//没有返回值的函数
  console.log("run");
}
fun0();

//3.2:方法可选参数
//当给age参数添加一个?的时候,代表的是age属性可以传递也可以不传递
function getInfo3(name: string, age?: number): string {
  if (age) {
    return `${name}---的年龄为---${age}`;
  } else {
    return `${name}---的年龄为---保密`;
  }
}
console.log(getInfo3("pip", 20));

//3.3:默认参数 es5中不可设置默认参数 但是es6和ts都可以设置默认参数
// 注意点:可选参数必须配置在最后面,就是类似直接把age设置为默认参数,直接给了默认值
function getInfo4(name: string, age: number = 20): string {
  if (age) {
    return `${name}---的年龄为---${age}`;
  } else {
    return `${name}---的年龄为---保密`;
  }
}
console.log(getInfo4("pia")); //pia---的年龄为---20
console.log(getInfo4("pia", 30)); //pia---的年龄为---30

//3.4:剩余参数
//借助三点运算符  传递的参数转化为数组的形式 
function sum(...result: number[]): number {
  let sum = 0;
  for (let i = 0; i < result.length; i++) {
    sum += result[i]
  }
  return sum
}
console.log(sum(1, 2, 3, 4));//10
console.log(sum(1, 2, 3, 4, 5, 6));//21

//3.5:函数的重载
//在java中方法中的重载:重载指的是两个或者两个以上的同名函数,但是他们的参数不一样,这就是函数重载的现象。
//typescript的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的
function getInfo0(name: string): string;
function getInfo0(age: number): number;
function getInfo0(str: any): any {
  if (typeof str === "string") {
    return "我的名字是" + str;
  } else {
    return "我的年龄是" + str
  }
}
console.log(getInfo0("pink"));//我的名字是pink
console.log(getInfo0(40));//我的年龄是40

//另一种写法
function getInfo5(name: string): string;
function getInfo5(name: string, age: number): string;
function getInfo5(name: any, age?: any): any {
  if (age) {
    return "我的名字是" + name + "我的年龄是" + age;
  } else {
    return "我的名字是" + name
  }
}
// console.log(getInfo5("paaa"));//我的名字是paaa
console.log(getInfo5("pa", 90));//我的名字是paaa 我的年龄是90

//3.6:箭头函数  this指向上下文
setTimeout(() => {
  console.log("run");//run
}, 3000)

(3):类与对象

(1):ES5创建对象

    //1:es5中最简单的类
    function Person() {
      this.name = "pin";
      this.age = 18;
    }
    let p = new Person();
    console.log(p.age); //18

    //2:构造函数和原型链中添加方法
    function Person1() {
      this.name = "pink";
      this.age = 12;
      this.run = function () {
        console.log(this.name + "在运动");
      }
    }
    //原型链上上面的属性会被多个实例共享  构造函数不会
    Person1.prototype.sex = "男";
    Person1.prototype.work = function () {
      console.log(this.name + "在工作");
    }
    let p1 = new Person1();
    p1.run(); //pink在运动
    p1.work(); //pink在工作

    //3:类的静态方法
    function Person2() {
      this.name = "pink";
      this.age = 12;
      this.run = function () {
        console.log(this.name + "在运动");
      }
    }
    //静态方法
    Person2.getInfo = function () {
      console.log("我是静态方法");
    }
    //原型链上上面的属性会被多个实例共享  构造函数不会
    Person2.prototype.sex = "男";
    Person2.prototype.work = function () {
      console.log(this.name + "在工作");
    }
    let p2 = new Person2();
    p2.work(); //pink在工作
    //调用静态方法
    Person2.getInfo();

    //4-1:es5中 类的继承 通过对象的冒充方式
    function Person3() { //父
      this.name = "ppp";
      this.run = function () {
        console.log(this.name + "在run");
      }
    }

    function Web() { //子 因为call方法用于继承,web继承了person3
      Person3.call(this); //就是在调用Web函数的时候,借助call方法改变this指向,指向到父类Person3,
      //但是没办法继承原型链上面的属性和方法  
    }
    let w = new Web();
    w.run(); //ppp在run 

    //4-2:es5中 原型链的继承
    //注意点:原型链实现继承:可以继承构造函数里面的属性和方法,还可以继承原型链上面的属性和方法
    function Person4() {
      this.name = "qqq"
      this.age = 12;
      this.saiHi = function () {
        console.log(this.name + "在说:" + "hi");
      }
    }

    function Web2() {

    }
    Web2.prototype = new Person4(); //利用原型链的方式,来继承了构造函数的属性和方法
    let w2 = new Web2();
    w2.saiHi(); //qqq在说:hi

    //4-2:es5中 原型链的继承 的问题
    //实例化的时候,没办法给父类传递参数  因此需要原型链和冒充父类的方式来实现完美继承
    function Person5(name, age) { //父
      this.name = name
      this.age = age;
      this.saiHi = function () {
        console.log(this.name + "在说:" + "hi"); //张一在说:hi
      }
    }
    Person5.prototype.sex = "女";
    Person5.prototype.work3 = function () {
      console.log(this.name + "在工作"); //张一在工作
    }

    function Web3(name, age) { //子
      Person5.call(this, name, age);
    }
    Web3.prototype = new Person5(); //利用原型链的方式,来继承了构造函数的属性和方法
    let w3 = new Web3("张一", 20);
    w3.saiHi();
    w3.work3();

(2):ts类的定义类

(01):ts中定义一个简单的类

注意点:创建实例对象,便会触发对应类的构造函数,因此在实例对象中传入参数,被构造函数接受后,进行赋值

class Person {
  name: string;//定义了属性
  constructor(name: string) {//构造函数 实例化类的时候,触发该函数
    this.name = name;
  }
  run(): void {
    console.log(this.name);
  }
}
let p = new Person("pink");//这边传递参数,实例化类后,触发构造函数,然后构造函数,接受传递过来的参数,进行赋值
p.run();//pink
(02):ts中的继承

使用entends来继承父类,并且在构造函数内使用super方法,来初始化父类的构造函数,两者结合,最终实现ts的继承

class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  run(): string {
    return `${this.name}在运动`
  }

}
// let p = new Person("liyi");
// console.log(p.run());//liyi在运动
//Web类来继承Person类
class Web extends Person {
  constructor(name: string) {
    super(name);//初始化父类的构造函数
  }
}
let w = new Web("xiaoxie");
console.log(w.run());//xiaoxie在运动
(03):父类和子类的方法一致

注意点:父类和子类的方法一致,优先调用子类的函数,若是子类没有改属性或者改方法,则去父类寻找

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

  run(): string {
    return `${this.name}在运动-父类`
  }
  work(): string {
    return `${this.name}在工作-父类`
  }
}
class Web extends Person {
  constructor(name: string) {
    super(name)
  }
  work(): string {
    return `${this.name}在工作-子类`
  }
}
let w = new Web("李侠");
console.log(w.run());//李侠在运动-父类
console.log(w.work());//李侠在工作-子类

(3):ts类的修饰符

typescript里面定义属性的时候,给我们提供了三种修饰符
public:公有 在类里面,子类 类外面都可以访问
protected: 保护类型 在类里面,子类都可以访问,但是在类外部不能访问
private:私有类型 在类可以访问,子类和类外部都不能访问
注意点:若是属性没有添加的那种类型的话,默认为共有属性

(01):public类型 --公有类型
//1:public类型的访问
class Person {
  public name: string;
  constructor(name: string) {
    this.name = name;
  }
  run(): string {
    return this.name + "在run";
  }
  work(): string {
    return this.name + "在工作";
  }
}
class Web extends Person {//子类 利用super继承了父类
  constructor(name: string) {
    super(name)
  }
  work(): string {
    return this.name + "在工作-子类"
  }
}
let w = new Web("小谢");
console.log(w.work()); //小谢在工作 - 子类
console.log(w.name);//小谢  在类外面调用类的属性name
(02):protected类型 --保护类型
//2:protected类型的访问
class Person {
  protected name: string;
  constructor(name: string) {
    this.name = name;
  }
  run(): string {
    return this.name + "在run";
  }
  work(): string {
    return this.name + "在工作";
  }
}
class Web extends Person {//子类 利用super继承了父类
  constructor(name: string) {
    super(name)
  }
  work(): string {
    return this.name + "在工作-子类"
  }
}
let w = new Web("小谢");
console.log(w.work()); //小谢在工作 - 子类
// console.log(w.name);//报错 因为name为保护类型  在外面不能被访问
(03):pricate类型 --私有类型
//3:private:私有类型  只能在本类中使用 子类和外部都不能访问
class Person {
  private name: string;
  constructor(name: string) {
    this.name = name
  }
  run(): string {
    return `${this.name}在run`
  }

}
let p = new Person("小哈");
// console.log(p.name);//报错,因为name为私有类型,只能在类里面使用
console.log(p.run());//小哈在run  这是因为run在Person类里面,可以使用name属性

(4):ts类的静态方法、属性

1:静态方法—就是使用static定义的方法,只能调用静态属性,调用静态方法—通过类.方法的方式调用
2:静态属性—就是使用static定义的属性
3:实例方法—就是通过实例对象调用的方法
4:实例属性—就是通过实例对象调用的属性

class Person {
  public name: string;
  static age: number = 10;
  constructor(name: string) {
    this.name = name;
  }
  run() {
    console.log(this.name + "在run");
  }
  work() {
    console.log(this.name + "在工作");
  }
  static print() {//静态方法,只能调用静态属性,不能调用类里面的属性
    console.log("我是静态方法,今年" + this.age + "岁了");
  }
}
let p = new Person("小谢"); //实例方法传入参数,触发构造函数,构造函数接受参数后赋值
p.work();//实例方法 就是实例化对象调用的方法   小谢在工作
Person.print();//调用静态方法  用static修饰的方法或者属性,直接通过类.调用  我是静态方法,今年10岁了
console.log(Person.age);//10

(5):ts的多态和抽象类

1:多态:是指父类定义的方法不去实现功能,而是通过继承的方式给了子类,子类继承父类的方法后,完成自己需要的功能,需要产生了多态性
需求 父类:动物类 子类:dog,cat继承了父类的吃的方法 输出狗吃肉,猫吃老鼠

class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  eat() {
  }
}
class Dog extends Animal {
  constructor(name: string) {
    super(name)
  }
  eat() {
    console.log(`${this.name}在吃肉`);
  }
}
class Cat extends Animal {
  constructor(name: string) {
    super(name)
  }
  eat() {
    console.log(`${this.name}吃老鼠`);
  }
}
let dog = new Dog("小狗");
dog.eat();//小狗在吃肉
let cat = new Cat("猫");
cat.eat();//猫吃老鼠

2:抽象类:ts提供了抽象类,就是定义了这个类为抽象类,让子类继承抽象类的方法,值得注意的是:抽象类不能实例化,但是子类可以实例化。
abstract关键字定义了抽象类和抽象方法,抽象类中的方法不包含具体实现并且必须在派生类实现
abstract方法只能放在抽象类里面
抽象类和抽象方法来定义标准
需求: Animal这个类为抽象了 要求他的子类必须包含eat方法

abstract class Animal {//抽象类和抽象方法  不能直接实例化,只能被其他子类继承
  public name: string;
  constructor(name: string) {
    this.name = name;
  }
  abstract eat(): any;
}
class Dog extends Animal {
  //抽象类的子类,必须实现抽象类的方法
  constructor(name: any) {
    super(name)
  }
  eat() {
    console.log(`${this.name}在吃肉`);
  }
}
class Cat extends Animal {
  constructor(name: any) {
    super(name)
  }
  eat() {
    console.log(`${this.name}在吃老鼠`);

  }
}
let dog = new Dog("小狗");
dog.eat();//小狗在吃肉
let cat = new Cat("小花猫");
cat.eat();//小花猫在吃老鼠

(6):接口

接口的作用:接口就是一种规范的定义,它定义了行为和动作的规范。(对类里面的方法和属性定义了规范)
接口分为:
1:属性接口
2:加密函数类型—接口
3:可索引接口
4:类类型接口
5:接口的扩展

(01):属性接口

接口:行为和动作的规范,还可以对批量方法进行约束
需求:定义一个姓名的接口,里面必须传入性和名

interface FullName {//interface 为接口关键字
  firstName: string;//接口中的对象是以;结束 
  lastName: string;
}
function printName(name: FullName) {
  console.log(name.firstName + '---' + name.lastName);
}
function printInfo(info: FullName) {
  console.log(info.firstName + '---' + info.lastName);
  //不能添加,info.age  因为传入的参数info: FullName,需要符合FullName接口的规范
}
// printName({
//   firstName: "小谢",
//   lastName: "渣渣"
// });  //小谢---渣渣
// 推荐把对象写在外面  只有对象里面包含firstName和lastName即可,复用性高
let obj = {
  age: 20,
  firstName: "小谢",
  lastName: "渣渣"
} //小谢---渣渣
printName(obj);
printInfo({
  firstName: "李",
  lastName: "仨"
}) //李---仨

接口—可选属性的定义 就是在定义接口的时候,对这个传入的参数设置为可选参数—以?设置

interface FullName {
  firstName: string;
  lastName?: string;
}
function getInfo(name: FullName) {
  console.log(name.firstName + "-" + name.lastName);
}
getInfo({
  firstName: "赵",
  // lastName: "子龙"
})//赵-undefined  因为lastName为可选参数,但是打印的话,未定义传入的参数

元素js模拟封装jq的ajax接口
/*
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ta: "{username:("#username").val(),content:$("#content").val()}",
dataType: “json”
})
*/

nterface Config {//配置的接口
  type: string;
  url: string;
  data?: string;
  dataType: string;
}
//原生js模拟jq封装的ajax
function ajax(config: Config) {
  let xhr = new XMLHttpRequest();
  xhr.open(config.type, config.url, true);
  xhr.send(config.data);
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        console.log("成功");
        let str = xhr.responseText;
        if (config.dataType === "json") {
          JSON.parse(str)
          console.log(JSON.parse(str));

        } else {
          console.log(xhr.responseText);
        }
      }
    }
  }
}

ajax({ //调用ajax接口
  type: "get",
  data: "name=lixi,age=20",
  // url: "http://www.baidu.com",//跨域了
  url: "http://a.itying.com/api/productlist",
  dataType: "json"
})
(02):加密函数类型—接口
interface encrypt {//encrypt ---加密
  (key: string, value: string): string;
}
let md5: encrypt = function (key: string, value: string): string {
  return key + "-" + value;
}
console.log(md5("name", "张三")); //name-张三
(03):可索引接口 : 对数组或者对象的约束 —不常用
interface UesrArr {
  [index: number]: string;
}
let arr: UesrArr = ["aa", "bb"];
console.log(arr[0]);//aa
(04):类类型接口 : 对类的约束 和抽象类有点相似
erface Animal {
  name: string;
  eat(name: string): void;
}
class Dog implements Animal { //implements---生效执行  Dog类去实现Animal接口
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  eat() {
    console.log(this.name + "在吃肉");
  }
}
let dog = new Dog("小黑");
dog.eat();//小黑在吃肉
class Cat implements Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  eat(food: string) {
    console.log(this.name + "吃" + food);
  }
}
let cat = new Cat("小花猫");
cat.eat("猫粮");//小花猫吃猫粮
(05):接口的扩展 接口可以继承接口
// interface Animal {
//   eat(): void;
// }
// interface Person extends Animal {
//   work(): void;
// }
// class Web implements Person {
//   name: string;
//   constructor(name: string) {
//     this.name = name;
//   }
//   eat() {
//     console.log(this.name + "吃肉");
//   }
//   work() {
//     console.log(this.name + "在工作");
//   }
// }
// let w = new Web("小谢");
// w.work();//小谢在工作

//继承并且实例化接口
interface Animal {
  eat(): void;
}
interface Person extends Animal {
  work(): void;
}
class Programmer {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  coding(code: string): void {
    console.log(this.name + code);

  }
}
class Web extends Programmer implements Person {
  // name: string;
  constructor(name: string) {
    // this.name = name;
    super(name)
  }
  eat() {
    console.log(this.name + "吃肉");
  }
  work() {
    console.log(this.name + "在工作");
  }
}
let w = new Web("小谢");
w.work();//小谢在工作
w.coding("写ts代码")//小谢写ts代码

(7):泛型

你可能感兴趣的:(ts梳理)