函数与类前言本文是Typescript学习系列文章,旨在利用碎片化时间快速高效地学习Typescript。.上篇回顾《你好,我叫Typescript 01 ── 数据类型》《你好,我叫Typescript 02 ── 变量与接口》《你好,我叫Typescript 03 ── 泛型》功能“蹦蹦”:好几天没见了。最近在学习Typescript的过程中遇到了一个新问题,急需大家的解答。“跳”:有什么问题,弹跳。《蹦蹦》:快乐星球是什么,什么是……错,什么是函数?TS函数和JS函数有什么区别?《跳》:那我带你一起学习。引入“跳转”:function是一种定义行为的语法,其实就是给JS添加额外的功能。同样可以创建命名函数和匿名函数。functionadd(num1:number,num2:number):number{returnnum1+num2;}console.log(add(1,2));//3letaddNum=(num1:number,num2:number):number=>num1+num2;console.log(addNum(1,2));//3我们可以为每个参数添加一个类型,然后为函数本身添加一个返回值类型。TypeScript可以自动从return语句中推断出返回类型,所以我们通常会省略它。简而言之,一个函数类型包括“参数类型”和“返回值类型”两部分。当写出一个完整的类型时,两部分都需要写完整。其实参数类型可以写成参数列表的形式,可以为每个参数指定名称和类型,增加代码的可读性。只要参数类型匹配,它就被认为是有效的函数类型,无论参数名称是否正确。第二部分是返回值类型。如前所述,返回值类型是函数类型的必要部分,如果函数不返回任何值,还必须将返回值类型指定为void,而不是留空。当在赋值语句的一侧指定类型而另一侧未指定类型时,TypeScript编译器会自动识别该类型。定义函数参数的方法1、直接声明函数参数functionadd(num1:number,num2:number):number{returnnum1+num2;}add(1,2);//32。解构赋值声明函数参数functionadd({num1,num2}:{num1:number,num2:number}):number{returnnum1+num2;}add({x:1,y:2});//33.剩余参数声明函数参数functionadd(...rest:number[]){returnrest.reduce((pre,cur)=>pre+cur);}add(2,3,4,5);//14add("yichuan",3);//报错不能使用String4.命名声明函数参数typeadd=(num1:number,num2:number)=>number;interfaceadd{(x:number,y:number):number}调用方法:letaddFun:add=>(num1,num2)=>num1+num2;5、可选参数和默认参数functionadd(num1:number,num2:number,num3?:number):number{returnnum1+num2;}显然:num1和num2是默认参数,num3是可选的选择参数。记住,默认参数放在前面,可选参数放在后面。JS中的this指向问题很烦人。this的指向是在调用函数的时候指定的,但是理解函数调用的上下文比较麻烦。事实上,两者之间并没有太大的区别。幸运的是,TS能够通知您哪里使用不当。函数重载函数重载或方法重载是创建多个具有相同名称和不同数量或类型参数的方法的能力。functionaddFun(num1:number,num2:number):number;functionaddFun(num1:string,num2:string):string;functionaddFun(num1:string,num2:number):string;functionaddFun(num1:number,num2:string):字符串;函数addFun(num1:any,num2:any):any{if(typeofnum1==="string"||typeofnum2==="string"){returnnum1.toString()+num2.toString();}returnnum1+num2;}console.log(addFun(1,2));《弹跳》:我们可以看到大部分库源码都是函数重载的方式,这是为什么呢?“跳转”:这是因为使用了函数重载后,其他人只要看到函数重载声明就可以知道这个函数是怎么调用的。函数重载的方式是ts会从头开始查找类型,匹配则返回函数类型,不匹配则转下一个。因此,在定义重载时,一定要将最精确的定义放在首位。"tips:在维护公共组件时,可以使用该方法让用户和后续维护人员快速知道如何调用该函数。"类“蹦蹦”:TS类和JS有什么区别?“跳转”:在es6之前,传统的Javascript需要使用函数和原型链继承来实现组件的复用,但这对于不了解JS原型链原理的程序员来说很难。ES6引入了类的思想,让程序员可以基于类进行面向对象的编程。“bounce”类的属性和方法:在面向对象的编程语言中,类可以创建对象的蓝图,描述要创建的对象的公共属性和方法。classPerson{//实例属性name:string;age:number;//私有字段#score:number;//静态属性staticheight:number=180;//readonlyweight:number=130;//Constructor(name:string,age:number,score:number){this.name=name;this.age=age;this.#score=score;}//实例方法getName(){returnthis.name;}//静态方法staticgetAge(){returnthis.age;}}letperson:Person=newPerson("wenbo",12);console.log(person.getName());console.log(Person.height);person.name="zhaoshun";console.日志(person.getName());Person.height=170;console.log(Person.height);person.weight=110;console.log(person.weight);实例属性(成员属性):直接在类中定义的属性就是实例属性,需要通过对象的实例来访问。静态属性(类属性):在属性前使用static关键字来定义类属性(静态属性),可以直接通过类访问。私有字段:在属性前面加上#将使该属性成为私有的,并且不能在包含类之外访问甚至检测到。每个私有属性唯一地定义了它包含的类,并且ts访问修饰符(public、private)不能用于私有属性。构造函数(执行初始化):创建对象时将调用构造函数。在实例方法中,this表示当前实例。在构造函数中,当前对象就是当前新建的对象,可以通过给新建的对象添加属性。实例方法(成员方法):在类中直接定义的方法就是实例方法,需要通过对象的实例来调用。在方法中,this可以用来表示当前调用该方法的对象。谁调用这个方法就指向谁。静态方法(类方法):在方法前使用static关键字定义一个类方法(静态方法),可以通过类直接访问。继承基于类的编程中最基本的模式之一是允许使用继承来扩展现有的类。classAnimal{move(distanceInMeters:number=0){console.log(`Animalmoved${distanceInMeters}m.`);}}classDogeextendsAnimal{bark(){console.log('Woof!Woof!');}}constdog=newDog();dog.bark();dog.move(10);dog.bark();如上所示,是最基本的继承:类继承基类的属性和方法。在这里,Dog是通过extends关键字从Animal基类派生的派生类。派生类通常称为子类,而基类通常称为超类。因为Dog继承了Animal的功能,我们可以创建一个Dog的实例,它可以bark()和move()。public、private和protected修饰符在TS中,可以为类的属性、方法和构造函数设置修饰符,以限制它们的作用范围。默认修饰符是public,所以程序中定义的成员可以被当前类和子类自由访问。“提示:在编写类时,养成添加成员修饰符的习惯。”classFather{//公共成员publicname:string;//私有成员privateage:number;//保护成员protectedaddress:string;publicconstructor(name:string,age:number,address:string){this.name=name;this.age=age;this.address=address;}publiceat(meters:number){console.log(`${this.name}moved${meters}`);}}classSonextendsFather{constructor(){super()}test(){console.log(this.name);//可访问console.log(this.age);//属性“age”为私有属性,只能在类“Father”中访问。console.log(this.address);//可访问}}constbigLiu=newFather("bigLiu",32,"四川成都");console.log(bigLiu.name);//可访问console.log(bigLiu.age);//age属性为私有属性,只能在Father类中访问。console.log(bigLiu.address);//“address”属性受到保护,只能在“父”类及其子类中访问。constsmallLiu=newSon();console.log(bigLiu.name);//可访问console.log(bigLiu.age);//age属性为私有属性,只能在Father类中访问。console.log(bigLiu.address);//“address”属性受到保护,只能在“父”类及其子类中访问。Accessors(访问器)TypeScript支持通过getters/setters拦截对对象成员的访问。它可以帮助您有效地控制对对象成员的访问。classGreeter{constructor(message:string){this.greeting=message;}greeting:string;gethello(){returnthis.greeting;}sethi(x){this.greeting=x;}}constx=newGreeter('eeee')x.hi('22');x.hello='2'//报错,不可修改。事实上,它使用getters/setters来拦截对对象成员的访问。解析后的源码如下:abstractclass用abstract关键字声明的类称为抽象类。抽象类不能实例化,因为它包含一个或多个抽象方法。所谓抽象方法是指不包含具体实现的方法:abstractclassPerson{constructor(publicname:string){}abstractsay(words:string):void;}//Cannotcreateaninstanceofanabstractclass.(2511)constlolo=newPerson();//Error抽象类不能直接实例化,我们只能实例化实现了所有抽象方法的子类。具体如下:abstractclassPerson{constructor(publicname:string){}//抽象方法abstractsay(words:string):void;}classDeveloperextendsPerson{constructor(name:string){super(name);}say(words:string):void{console.log(`${this.name}says${words}`);}}constlolo=newDeveloper("lolo");lolo.say("Ilovets!");//lolosaysIlovets!Summary"跳转》:其实这篇文章主要介绍:函数和类的概念,继承,各种属性等等。参考文章《重学TS》《TS中文文档》by宝哥
