本文基于Javascript基础
TS引入了静态类型系统,需要先通过编译器(如TypeScript编译器tsc)将TypeScript代码编译成JavaScript代码,然后再在浏览器中执行。这一过程中会进行类型检查、转译等,以确保代码的正确性和可执行性。提供了更强大的面向对象编程支持,包括类、接口、抽象类等概念。这些特性在开发大型应用时非常有用,有助于提高代码的可维护性和可重用性。
TS常用类型
- 可以进行类型检查,同一个变量只能存放一种类型
// 代码模块,函数里面我们都可以定义我们的局部变量;
// var a = 值;
// var 变量名字: 类型 = 默认值, typescript在赋值的时候,注意, 类型要一致;
var a: boolean = false;
// 基本类型呢?string, boolean, number, Function, any
var b: string = "helloworld";
console.log(b);
var c: number = 7;
console.log(c);
var d: Function = function() {
console.log("d function");
}
d();
// 和JS一样,任意类型都可以赋值
var e: any = 7;
e = "helloword";
// let 来定义局部变量,var 用法也是类似的; let/var的区别是什么?
// 当你运行的时候,如果定义了,超过了这个作用域, 还可以使用,let就不一样;
// let --->var
/*if(true) {
var testNum: number = 7777;
}
console.log(testNum);
if(true) {
let testNum2: number = 8888;
}
console.log(testNum2);*/
// 函数: 函数名字,参数,返回值
// function 函数名字(参数名字: 参数类型, ...): 返回值类型(void) {}
function test(lhs: number, rhs: number): number {
return lhs + rhs;
}
console.log(test(3, 4)); // 7
类和面向对象
// 定义一个类 class 关键字
// class 类名 {}
class A { // 类的开始
// 权限: public ,private, protected
// 权限 名字: 类型 = 默认值;
// public: 类的外部可以使用: 外面的代码,
// private: 只能在类的内部
// protected: 类的内部使用,被继承了,子类是可以使用的;
// 不写权限,Java, C++,默认是private, TypeScript, 默认是public;
//
private isDebug: boolean = false;
private aa: number = 0;
constructor() {
console.log("constructor");
this.aa = 100; //
}
// 权限 函数名字(参数名字: 参数类型, ...): 返回值类型(void) {}
public foo(lhs: number, rhs: number): number {
// this --->类的实例
return lhs + rhs;
}
} // 类的结束
var a: A = new A(); // js 相似 new 一个实例的时候---》掉一下 constructor
console.log(A); // A ---> js 运行 就是函数;
console.log(a); // 类的实例,就会包含这个数据成员;
console.log(a.foo(3, 4)) // 7;
console.log(A.prototype.foo);
// console.log(a.__proto__.foo);
console.log((a as any).__proto__.foo); // tsc ---> ts --->js;
类的继承、单例
class Person {
private name: string = "";
protected age: number = 0;
protected height: number = 0;
// ...
public test(): void {
console.log("person test");
}
constructor() {
console.log("Person constructor");
}
}
// class 类名 extends 基类 {}
// Man.prototype: {test: function, __proto__: {test: person, function}}
class Man extends Person {
private sex: number = 0;
public foo(): void {
this.age = 77;
}
constructor() { // 先要调用基类的构造函数,super(); 做自己构造函数,不调用super 就会报错;
super(); // 调用父类的构造函数;
console.log("Man constructor");
}
public test(): void {
super.test(); // 调用父类---> js 显示传递this person.call(this);
console.log("man test");
}
}
// ts 里面是没有多态,底层key不能重复;
var m: Man = new Man(); // Man is Person
console.log(m); //
m.foo();
// 所有函数默认有虚函数的特性
m.test();
// 全局唯一的一个实例;
class Game {
public static Instance: Game = new Game(); // 单例;
public test(): void {
console.log("Game test");
}
}
Game.Instance.test();
枚举、Lambda表达式、名字空间、as关键字、import
// 使用一个有意义的名字---》数字
// enum 名字 { 名字 = 1, 名字2 = 2 }
enum Status {
Idle = 1,
Walk = 2,
Attack = 3,
Dead = 4,
}
console.log(Status); // 双向表的实例 Idle--->1 ---> 1--->Idle;
var s: Status = Status.Idle;
console.log(s);
// 如果这里不写数据,自动基于上一个递增1
// 虽然底层是一个表,但是我们不要去修改这个值;
enum GameStatus {
Idle = 0,
Walk, // Walk = 1;
Attack = 5,
Dead, // Dead = 6;
}
console.log(GameStatus);
// GameStatus.Idle = 7; // 编译的时候, 要求只读
// (GameStatus as any).Idle = 7; // 强制改;
// console.log(GameStatus);
var a = function() {
console.log("test");
}
a();
var func = ()=>{ // lamda 写这个函数-->this --->传递到函数里面;
console.log("lamda func");
};
func(); // this 传递
class Man {
private age: number = 0;
public foo(endFunc: Function): void {
endFunc(); // 调用函数(lamda --->传这个函数当前this, 普通就不会传递this)
}
public test() {
// this ---> 对象实例
this.foo(()=>{
// this对象实例
console.log(this);
})
this.foo(function() {
// this 不确定了;
// console.log(this); // 不确定的值
})
}
}
var m: Man = new Man();
m.test();
// 名字空间: 显卡厂商A, SDK, 显卡厂商B也提供一套SDK, setPoint() --->冲突;
// SDK的时候,会有自己的名字空间;
namespace A {
export function setPoint(): void {
console.log("A setPoint");
}
}
namespace B {
export function setPoint(): void {
console.log("B setPoint");
}
}
A.setPoint();
B.setPoint();
// 类型强转:
// 子类的实例---》基类的变量;
class Person { // 基类,父类
}
class Woman extends Person {
}
// 强转你要转的有道理
var p: Person = new Woman() as Person;
var temp: number = GameStatus.Idle;
// 写代码不可能,在一个文件里面一直写; 代码要分文件,分模块,文件A, 使用文件B定义的类; export/import;
// export 把当前模块的东西导出给外部使用;
// import 把外部导出的东西,导入进来使用;
// 你要使用外部,导入import;
import MyGameMgr from "./GameMgr"; // 导入外部模块的default
// import GameMgr from "./GameMgr";
console.log(MyGameMgr); // ---> GameMgr
import {Timer, Timer2} from "./GameMgr" // 这里打导出,就必须要模块里面有这个名字;
// import {Timer2} from "./GameMgr"
console.log(Timer, Timer2);
普通导出export、默认导出default
// 开放给外部使用,你就要导出; export
// default导出: 每个代码只有一个默认导出;
export default class GameMgr {
private isPlaying: boolean = false;
private isGameStart: boolean = false;
private score: number = 100;
// ....
}
// 普通导出:
export class Timer {
private expTime: number = 0;
// ....
}
export class Timer2 {
private expTime: number = 0;
// ....
}