变量声明
// for(var i:number=0;i<10;i++){
// setTimeout(function(i:number){
// console.log(i);
// },0,i)
// }
接口
对象接口
- 基本格式
var obj:{a:number,b:number}={a:1,b:2};
- 修改值
obj.a=10;
obj.b=30;
- 添加属性
// c就是缺省属性
var obj:{a:number,b:number,c?:number}={a:1,b:2};
obj.c=40;
- 删除属性:只能删除缺省属性。a,b是必要属性,无法删除
delete obj.c;
- 对象任意添加属性:
[key:string]:numberkey就是属性名变量,string是属性名的类型,:number值的类型
// var obj:{[key:string]:number}={a:1,b:2}
// obj.c=3;
// obj.d=4;
// obj.e="a";
-
定义接口类型
- interface 大写字母 开头
- 接口中不允许赋值
interface IObj{ a:number; b:number; c?:number; } var obj:IObj={a:1,b:2}; var obj1:IObj={a:2,b:3};
总结:
- 如果有两个对象的类型一致时,可以定义一个接口类型
函数接口
- 函数类型
// fn:(a:number,b:number)=>void 箭头后面的void指的是函数返回类型
// (a,b)=> 是箭头函数
const fn:(a:number,b:number)=>void=(a,b)=>{
}
- 外面定义函数类型
interface IFn{
(a:number,b:number):void;
}
const fn:IFn=(a,b)=>{
console.log(a,b);
}
- 接口写法
var fn:IFn=(a,b)=>{
return a+b;
}
var fn1:(a:number,b:number,c?:number)=>number=(a,b,c)=>{
if(c) return a+b+c;
return a+b;
}
interface IFn{
(a:number,b:number,c?:number):number;
}
只读接口
- 不能被修改,不能被
删除(只能是可选参数),不要设置缺省值,否则就无意义
interface IObj{
a:number;
b:number;
c?:number;
readonly d:number;
}
var obj:IObj={a:1,b:2,d:3};
var obj1:IObj={a:2,b:3,d:4};
// obj.d=10;
// delete obj.d;
下标接口
- 包含下标的接口
interface IList{
[index:number]:string|number
}
// var arr:IList=[1,2,"c","b"];
var arr:IList={};
arr[0]=3;
arr[1]="a";
console.log(arr)
类接口类型
- 只要类中有这个Iclass接口中有描述的属性和方法,那么这个类实例化后的对象就认为是这个接口类型
- 可以向下降级符合要求,也就是说:IClass中可以只定义一个,不会报错。
巧合型一样
interface IClass{
a:number;
play():void;
}
class Box{
a:number=1;
constructor(){
}
play(){
console.log("play")
}
}
class Ball{
a:number=1;
constructor(){
}
play(){
console.log("ball play")
}
}
var b1:IClass=new Box();
var b2:IClass=new Ball();
var arr:Array<IClass>=[b1,b2];
// var arr:Array<Box|Ball>=[b1,b2];
通过类实现接口:必要实现
- implements:实现接口,表示当前类必须满足这个接口中定义的属性和方法。也就是说interface中有什么方法,那么类中也必须要有!!
interface IUpdate{
update():void;
}
class Box implements IUpdate{
constructor(){
}
update(): void {
console.log("aaa")
}
}
class Ball implements IUpdate{
constructor(){
}
update(): void {
console.log("bbb")
}
}
var arr:Array<IUpdate>=[new Box(),new Ball()];
arr.forEach((item:IUpdate)=>{
item.update();
})
实现多个接口类型
// 定义公有类型
interface IUpdata{
update():void
}
interface IHuman{
name:string,
sex:string,
age:number
}
interface IRender{
render():void
}
// A类型继承IUpdata,IHuman
class A implements IUpdata,IHuman{
name:string="zhangsan"
sex: string='男'
age: number=20
update(): void {
console.log('update')
}
}
// B类型继承IRender,IHuman
class B implements IRender,IHuman{
name:string="wangli"
sex: string="女"
age: number=22
render(): void {
console.log('render')
}
}
var arr:Array<IHuman>=[new A(),new B()]
console.log(arr)
构造函数接口
- 传参时传入类类型,传入的是一个类名
interface IUpdate{
update():void;
// 这里是不能定义静态属性和方法,只能定义实例化
}
// 构造函数接口中才可以定义静态属性和静态方法
interface IBox{
new (a:number,b:number):IUpdate
a:number;//类属性 静态属性
play():void; // 类方法 静态方法
}
class Box implements IUpdate{
static a:number=2;
constructor(a:number,b:number){
}
update(): void {
console.log("update");
}
static play(){
// 只有上面定义了类方法,这边才可以使用
}
}
class Ball implements IUpdate{
static a:number=1;
constructor(a:number,b:number){
}
update(): void {
console.log("update1")
}
}
function create(B:IBox){
var a:IUpdate=new B(1,2);
console.log(a);
}
create(Box);
// create(Ball);
继承接口
- 类只能继承一个类
class A{
a:number=1
}
class B{
play():void{
console.log('play')
}
}
class C extends B{
}
- 接口继承一个接口,也可以继承多个接口
interface IA{
a:number;
}
interface IB{
b:number;
}
// 接口可以继承多个接口
interface IC extends IA,IB{
c:number;
}
class C implements IC{
a: number=1;
b: number=2;
c: number=3;
}
接口继承类
- 类中的所有属性和方法必须使用公有的
class Box{
a:number=1;
b:number=2;
play():void
{
console.log("play")
}
}
interface IBox extends Box{
c:number;
}
class Ball implements IBox{
c: number=2;
a: number=1;
b: number=3;
play(): void {
console.log("plays")
}
}
混合类型
- 如果在创建时无法实现这个接口定义的所有属性和方法,可以断言在增加
interface IFun{
(a:number,b:number):void;
num:number;
play():void;
}
// 泛型
// var fn:IFun=<IFun>((a,b)=>{
// console.log(a,b);
// })
var fn:IFun=((a,b)=>{
console.log(a,b);
}) as IFun;
fn.num=3;
fn.play=function(){
console.log("play");
}
类
- 构造函数不能返回类型
- set方法不能有返回类型
- private 私有的
- public 公有的
- protected 受保护的
| -- | 实例化是否可以调用 | 当前类中是否可以调用 | 继承后子类是否可以调用 |
|---|---|---|---|
| private 私有的 | 不行 | 可以 | 不行 |
| public 公有的 | 可以 | 可以 | 可以 |
| protected 受保护的 | 不行 | 可以 | 可以 |
- 总结:public(公有的)干啥都行,private (私有的)只能在类中调用,protected(受保护的) 实例化之后不能调用
- 构造函数可以使用这三个修饰符的
- 在当前类中,不管定义任何修饰符,都可以调用并且执行
export default class Box{
// private 私有的
// public 公有的
// protected 受保护的
// 构造函数不能返回类型
// 构造函数可以使用这三个修饰符的
public a:number=1;
protected b:number=2;
private c:number=3;
constructor(){
// console.log(this.a);
// console.log(this.b);
// console.log(this.c);
// this.play();
// this.run();
// this.jump();
this.walk();
}
public play():void
{
console.log("play")
}
protected run():void
{
console.log("run")
}
private jump():void{
console.log("jump");
}
private walk():void
{
console.log('walk');
this.jump();
this.play();
this.run();
}
// set方法不能有返回类型
// set num(value:number){
// }
// get num():number{
// return 1;
// }
}
实例化对象只能调用public定义的属性和方法
只有公有的才可以调用
继承后,子类可以调用父类的 public和protected定义属性和方法,private定义的不能调用
继承后,
- 子类重新覆盖超类方法时,受保护得到可以重新定义为公有的,
- 但是公有的不能修改为受保护的,
- 在子类中不能重新覆盖创建父类的私有属性和方法
总结:
- 如果仅在当前类中使用,实例化对象不调用,子类中不重写不调用,定义为私有的private
- 如果希望在子类中可以调用,重新,但是不需要实例化对象调用,不对外暴露,定义为受保护的 protected
- 如果希望实例化对象调用,完全调用在外的,定义为公有的public
构造函数:
- 当构造函数设置为private私有时,意味这个类不能继承,而且也不能在其他地方实例化对象,一般来说这种写法用于单例模式(实现这个类的时候可以创建一个唯一实例化对象,可以在任何地方使用,防止实例化对象被覆盖,因此我们可以给他做一个私有的)
- 如果构造函数设置为protected受保护时,以为这个类不能在出除当前类和子类以外的地方实例化,可以用于继承,当前类仅用于基类不需要实例化,仅单例模式存在
- 如果构造函数设置为public,公有时,可以在任意位置实例化当前对象
单例模式
- 全局的唯一一个实例化对象,可以在全局的任意一个位置调用它,可以存储值,修改值,可以抛发,可以接收事件的中建核心
静态属性
抽象类abstract
- 类可以被继承,并不能被实例化
- 抽象类除了具备类的特征,还有接口的特征
- 目的就是在抽象类中实现部分基础的方法和属性,用于继承使用,而使用abstract实现抽象方法设定,需要在子类中详细描述
- abstract static不能一起使用
- 要求所有的属性和方法必须是public才可以使用作为接口
- 接口中所有的属性和方法实现时,都必须是public公有的
函数
匿名函数
- 后复制
命名函数
- 先复制
函数知识点
- 参数
var fn:(a: number, b: number) => void=function(a,b){
console.log("aa")
}
-
this 参数
- 参数类型的添加
// 鼠标点击屏蔽触发abc()函数
class Box{
private clickFn:(e:MouseEvent)=>void;
constructor(){
this.clickFn=(e:MouseEvent)=>this.clickHandler(e);
document.addEventListener("click",this.clickFn);
}
private clickHandler(this:Box,e:MouseEvent){
this.abc();
}
private abc(){
console.log("bac")
}
}
new Box()
interface IObj{
a:number;
}
function fn(this:IObj,a:number){
this.a=a;
}
fn.call({a:1},1);
函数重载
- 参数不一样
- 类型不一样
function getConcat(a:string,b:string):string;
function getConcat(a:Array<number>,b:Array<number>):Array<number>;
function getConcat(a:any,b:any):any{
if(typeof a==="string" && typeof b==="string"){
return a+b;
}else{
return a.concat(b);
}
}
var str:string=getConcat("a","b");
var arr:Array<number>=getConcat([1,2,3],[4,5,6]);
// var arr1:Array<string>=getConcat(["a","b"],["c","d"]);
泛型
- T类型:T就是个变量,在执行它的时候执行他的变量
function getValue<T>(arg:T):T{
return arg;
}
getValue<number>(1) // 1
- 一般泛型作为T,U作为第二类变量
function concat<T,U>(a:T,b:U):T|U{
return a;
}
concat<string,number>("a",1);
// 计算得到1+2=3
interface IFn<T>{
(a:T,b:T):void
}
var fn:IFn<number>=(a,b)=>{
console.log(a+b);
}
fn(1,2);
- 函数泛型接口
// interface IFn<T>{
// (a:T,b:T):void
// }
// var fn1:IFn<number>=function(a:number,b:number):void
// {
// }
- 泛型类型接口
// interface IFns{
// <T>(a:T,b:T):void
// }
// function getFn<T>(a:T,b:T):void{
// }
// var fn:IFns=getFn;
// fn<number>(1,2)
- 泛型类
class Box<T>{
a:T;
constructor(a:T){
this.a=a;
}
}
var b:Box<number>=new Box(1);
var b:Box<string>=new Box("a");