//?为可选参数 可选参数必须配置在最后面
//可用默认参数,但不能和?用在一起
function fun1(name:string='li', age?:number):string{ //规定返回值为string类型
return `${name}--${age}`
}
console.log(fun1('san'))
console.log(fun1('san', 10))
let fun2 = function():void{ //无返回值
console.log(11)
}
function sum(...res:number[]):number{ //需要存在一个数组中
let sum:number = 0
for(let i = 0; i<res.length; i++){
sum += res[i]
}
return sum
}
console.log(sum(1,2,3))
function ali(num1:number,...num2:number[]):number{ //三点运算符要放在最后面
return num1
}
//数组第一个值放在num1中
console.log(ali(1,2,3))
class Person{
name:string
constructor(n:string){ //构造器 实例化类的时候触发的方法
this.name = n
}
getName():string{
return this.name
}
setName(name:string):void{
this.name = name
}
}
let p = new Person('li')
console.log(p.getName())
p.setName('zhang')
console.log(p.getName())
class Person{
name:string
constructor(n:string){ //构造函数 实例化类的时候触发的方法
this.name = n
}
getName():string{
return this.name
}
setName(name:string):void{
this.name = name
}
}
//继承
class Web extends Person{
constructor(name:string){
super(name) //super表示调用父类的构造函数 constructor
//将形参name存的值传到Person构造器的n中
}
man(){ //不能用this.man = function(){}
console.log('man')
}
}
let w = new Web('wang')
console.log(w.getName())
w.man()
class Person{
public age:number = 20
protected name:string
private sex:string = 'male'
constructor(age:number, name:string, sex:string){ //构造函数 实例化类的时候触发的方法
this.name = name
this.age = age
this.sex = sex
}
getName():string{
return this.name
}
setName(name:string):void{
this.name = name
}
getAge():void{
console.log(this.age) //类内访问
}
}
//继承
class Web extends Person{
constructor(age:number, name:string, sex:string){
super(age, name, sex)
}
work(){
console.log(this.name) //访问protected name
// console.log(this.sex) 错 不能访问
}
}
let p = new Person(20, 'li', 'male')
console.log(p.age) //访问public age
// console.log(p.name) 错
// console.log(p.sex) 错
let w = new Web(30, 'wang', 'female')
w.work()
class Per{
public name:string = 'wang'
static age:number = 20
constructor(name:string){
this.name = name
}
run(){ //实例方法 只能通过实例调用
console.log(`${this.name}在运动`)
}
static work(){ //静态方法不能直接调用类里的属性,只能调用静态属性
console.log(`我的年龄是${this.age}`)
}
}
let p = new Per('wang')
p.run()
Per.work() //静态方法可以直接调用
就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法
不用为了对不同的参数类型或参数个数,而写多个函数。多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数
function getInfo(name:string):string
function getInfo(age:number):string
function getInfo(str:any):any{
if(typeof str === 'string') return '我叫 ' + str
else return '我的年龄是 ' + str
}
console.log(getInfo('zhangsan'))
console.log(getInfo(20))
//console.log(getInfo(true)) //错 没有布尔型的函数声明
//可选参数的重载
function get(name:string):string
function get(name:string, age:number):string
function get(name:any, age?:any):any{
if(age) return '我叫 ' + name + '我的年龄是 ' + age
else return '我叫 ' + name
}
console.log(get('li'))
// console.log(get(123)) 错误
console.log(get('li', 20))
// console.log(get('li', true)) 错误
class Animal{
name:string
constructor(name:string){
this.name = name
}
eat(){
console.log('吃的方法')
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name + '吃骨头'
}
}
let d = new Dog('狗狗')
d.eat()
abstract class Animal{
public name:string
constructor(name:string){
this.name = name
}
abstract eat():any
}
// let a = new Animal() 错误 抽象类不能直接被实例化
class Dog extends Animal{
//抽象类的子类必须实现抽象类中的抽象方法
constructor(name:string){
super(name)
}
changeName(){
this.name = '阿猫阿狗'
console.log(this.name)
}
eat(){
console.log(this.name + '吃骨头')
}
}
let d = new Dog('狗狗')
d.eat()
d.changeName()
function printLabel(label:string):void{ //约束传入字符串且无返回值
console.log('print')
}
function print(labelInfo:{label:string}):void{
console.log('labelInfo')
}
// print('haha') 错误
// print({name: 'haha'}) 错误
print({label: 'wang'})
//interface关键字定义接口
interface FullName {
firstName: string
secondName?: string //可选属性
}
function printName(name:FullName){ //必须传入对象firstName secondName
console.log(name.firstName + name.secondName)
}
// printName(20,'zhang','san') 错 只能传两个字符串
let obj={
age: 20,
secondName: 'san', //可以多传
firstName: 'zhang' //顺序可以颠倒
}
printName(obj) //可以
//接口实例作用 封装 ajax
//约束了属性的名字和类型
interface Config{
type:string
url:string
data?:string
dataType:string
}
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 && xhr.status === 200){
console.log('success')
//JSON.stringify()的作用是将 JavaScript 对象转换为 JSON 字符串,而JSON.parse()可以将JSON字符串转为一个对象。
if(config.dataType === 'json') JSON.parse(xhr.responseText)
else console.log(xhr.responseText)
}
}
}
ajax({
type:'get',
data:'name=zhangsan',
url:'www.baidu.com',
dataType:'json'
})
//对方法传入的参数及返回值进行约束
interface encrypt{
(key:string, value:string):string
}
//名可以不同 但是类型得相同
let md5:encrypt = (keys, values) => {
return keys + values
}
console.log(md5('name', 'zhang')) //得传入两个string
//对数组、对象的约束
var arr:number[] = [222,333] 正常定义数组的方式
var arr1:Array<string> = ['222','333']
interface UserArr{
[index:number]:string //number是索引值的数据类型 string是value的数据类型
}
let arr:UserArr = ['aaa', 'bbb']
console.log(arr[0])
interface UserObj{
[index:string]:string | number
}
let obj:UserObj = {name:'张三', age:20}
//对类的约束 和 抽象类有点类似
interface Animal{
name:string
eat(str:string):void
}
//implements 使用类接口
class Dog implements Animal{
name:string
constructor(name:string){
this.name = name
}
eat(){ //没有参数也可以
console.log(this.name + '吃骨头')
}
}
let d = new Dog('狗狗')
d.eat()
class Cat implements Animal{
name:string
constructor(name:string){
this.name = name
}
eat(food:string){ //没有参数也可以
console.log(this.name + '吃骨头')
}
}
let c = new Cat('喵喵')
c.eat('food')
interface Animal{
getName():void
}
interface Person extends Animal{
getFood():void
}
class Web implements Person{
name:string
food:string
constructor(name:string, food:string){
this.name = name
this.food = food
}
getName(){
console.log(this.name)
}
getFood(){
console.log(this.name + '吃' + this.food)
}
}
let w = new Web('小李', '米')
w.getFood()
class Pro{
work:string
constructor(work:string){
this.work = work
}
}
class Code extends Pro implements Person{
constructor(name:string, food:string, work:string){
super(work)
}
getName(): void {
}
getFood(): void {
}
}
function getData<T>(value:T):T{
return value
}
getData<number>(123)
getData<string>('123')
//或者可以将返回值设为any
function getNum<T>(value:T):any {
return '1233'
}
getNum<number>(123)
class MinClass<T>{
public list:T[] = []
add(num:T){
this.list.push(num)
}
min():T{
let minNum = this.list[0]
for(let i=0;i<this.list.length;i++){
if(minNum > this.list[i]){
minNum = this.list[i]
}
}
return minNum
}
}
let m = new MinClass<number>() //实例化类并且指定了T代表的类型是number
//写法1
interface ConfigFn{
<T>(value:T):T
}
let getData:ConfigFn = function<T>(value:T):T{
return value
}
getData<string>('12')
//写法2
interface Config<T>{
(value:T):T
}
function getData<T>(value:T):T{
return value
}
let myGetData:Config<string> = getData
myGetData('2000')
//平常做法
class User{
username:string | undefined
password:string | undefined
}
class MysqlDB{
add(user:User):boolean{
console.log(user)
return true
}
}
let u = new User()
u.username = '张三'
u.password = '123'
let db = new MysqlDB()
db.add(u)
class User{
username:string | undefined
password:string | undefined
}
class MysqlDB<T>{
add(info:T):boolean{
console.log(info)
return true
}
}
let u = new User()
u.username = '张三'
u.password = '123'
let db = new MysqlDB<User>() //验证
db.add(u
//在类声明之前被声明 紧靠着类声明
//普通装饰器
function logClass(params:any){
console.log(params) //params就是当前类
params.prototype.apiURL = '动态扩展的属性'
params.prototype.run = function(){
console.log('这是一个run方法')
}
}
@logClass
class HttpClient{
constructor(){}
getData(){}
}
let http:any = new HttpClient()
console.log(http.apiURL)
http.run()
//装饰器工厂
function logClass(params:any){
return class extends params{
apiURL:string = '修改后的api'
getData(){
this.apiURL = this.apiURL + '--'
console.log(this.apiURL) //如果里面
}
}
}
@logClass
class HttpClient{
public apiURL:string | undefined
constructor(){
this.apiURL = '修改前的api'
}
getData(){
console.log(this.apiURL)
}
}
let http:any = new HttpClient()
console.log(http.apiURL)
http.getData()
function logProperty(params:any){
return function(target:any, attr:any){
console.log(target) //指向类
console.log(attr) //指向要修饰的属性
target[attr] = params
}
}
class HttpClient{
@logProperty('修改后的api')
public url:any | undefined
constructor(){}
getData(){
console.log(this.url)
}
}
let p = new HttpClient()
p.getData()
function get(params:any){
return function(target:any, methodName:any, desc:any){
console.log(target)
console.log(methodName)
console.log(desc)
target.apiURL = '新增api'
target.run = function(){
console.log('新增方法')
}
}
}
class HttpClient{
public url:any | undefined
constructor(){}
@get('www.baidu.com')
getData(){
console.log(this.url)
}
}
let http:any = new HttpClient()
console.log(http.apiURL)
http.run()*/
//方法装饰器将数组全部变成字符串
function get(params:any){
return function(target:any, methodName:any, desc:any){
console.log(target)
console.log(methodName)
console.log(desc)
let oMethod = desc.value
desc.value = function(...args:any[]){ //这么写是替换desc.value
args = args.map((value)=>{ //而不是重写
return String(value)
})
console.log(args)
oMethod.apply(this, args) //重写
}
}
}
class HttpClient{
public url:any | undefined
constructor(){}
@get('www.baidu.com')
getData(...args:any[]){
console.log(args)
console.log('我是getData里面的方法')
}
}
let http:any = new HttpClient()
http.getData(123, 'xx')
function logParams(params:any){
return function(target:any, methodName:any, paramsIndex:any){
console.log(params)
console.log(target)
console.log(methodName)
console.log(paramsIndex)
target.apiURL = params
}
}
class HttpClient{
public url:any | undefined
constructor(){}
getData(@logParams('xx') uuid:any){
console.log(uuid)
}
}
let http:any = new HttpClient()
http.getData('123')
console.log(http.apiURL)