TS 基础学习 第三篇

160 阅读3分钟

前言

 努力学习,希望每天进步一点。
 

A.方法装饰器

  function age (constructor:function){
       constructor.prototype.age=18
  }
  function method(target:any,propertyKey:string){
     console.log(target)
     console.log('prop'+propertyKey)
  }
  @age
  class Hello{
       name:string;
       age:string;
       constructor(){
        console.log('hello')
        this.name='casey'
       }
  }
  @method
  hello(){
     return 'hello method'
  }
  @method
  static shello(){
     return 'static method'
  }
  // console.log(Hello.prototype) // { hello: [Function (anonymous)], age: 18 }
// 我们修饰的hello这个实例方法,第一个参数将是原型对象,Hello.prototype

// console.log(Hello.prototype.constructor) // [Function: Hello] { shello: [Function (anonymous)] }

B.可传参的方法装饰器

// 参数装饰器表达式会在运行时当做函数被调用
function log(config){
  return function (target:any,name:string):void{
  console.log(target,name)
  let old=target[name]
  target[name]=function(){
    if(config=='top'||config=='all'){
      console.log('hello')
    }
    old()
    if(config==='bottom'||config==='all'){
     console.log('world')
    }
  
  }
  }
}

class Person{
   @log('top')
   say():void{
    console.log("我是原来的say方法")
   }
   @log('all')
   run():void{
    console.log('我是原来的run方法')
   }
}
 let demo=new Person()
  demo.say()
  demo.run()
  

C.属性装饰器

    // 属性装饰器会在运行时当做函数被调用
   // 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
   // 2、成员的名字
   function Value(value:string){
      return function(target:any,propertyName:string){
      target[propertyName]=value
      }
   }
   class Hello{
   @Value('博文') name:string
   
   }
   // console.log(new Hello().name)

D.装饰器加载顺序

function One() {
    return function(target) {
        console.log('I am class One')
    }
}

function Two() {
    return function(target, methodName: string) {
        console.log('I am method-class Two')
    }
}

function Three() {
    return function(target, paramsName: string) {
        console.log('I am params-class Three')
    }
}

function Four() {
    return function(target, paramsName: string) {
        console.log('I am params-class Four')
    }
}

function Five() {
    return function(target, protoName: string) {
        console.log('I am proto-class Five')
    }
}

@One()
class Hello {
    @Five()
    hello: string

    @Two()
    haha( @Three() p1: string, @Four() p2: string ) {
        console.log(p1, p2)
    }
}
// 方法和属性装饰器,谁在前面先执行谁,因为参数是属于方法的一部分,所以参数会一直紧紧挨着方法执行   5  2
// 方法和方法参数中,参数装饰器先执行   5 3 4 2 / 5 4 3 2
// 有多个参数装饰器时:从最后一个参数依次向前执行  5 4 3 2
// 类装饰器总是最后执行  5 4 3 2 1

// @One()
// class Hello {
//     @Two()
//     haha( @Three() p1: string, @Four() p2: string ) {
//         console.log(p1, p2)
//     }

//     @Five()
//     hello: string
// }


E.对象接口

   // 对象接口可以用来设定或限制对象里面每个属性的类型
interface a { a: number, b: boolean, c: string }

// 这样就可以给这个变量赋值满足接口数据类型的对象
let obj: a = {
    a: 123,
    b: true,
    c: 'aa'
}
console.log(obj)

F.类接口

  interface UserInterface {
    name: string;
    age: number;
    say(): void
}
// 类和接口建立关联,靠implements建立,只要建立了关系,那么我们的类型就必须严格实现接口中的每个属性和方法
class User implements UserInterface {
    constructor(public name: string, public age: number) {}
    say(): void {
        console.log('脱贫脱单不脱发!')
    }
}

let user = new User('xiaolun', 18)
console.log(user)
user.say()

G.接口

function printFn(obj: {label: string}) {
    console.log(obj.label)
}

let myObj = {size: 1, label: 'hello world'}
printFn(myObj)

// 用接口改写上面的示例
interface ObjValue {
    label: string
}

function printFun(obj: ObjValue) {
    console.log(obj.label)
}

let myObj2 = {size: 1, label: 'hello world22222'}
printFun(myObj2)

// 可选属性
interface SquareConfig {
    color?: string;
    width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
    let newSquare = {color: 'white', area: 100}
    if(config.color) {
        newSquare.color = config.color
    }
    if(config.width) {
        newSquare.area = config.width
    }
    return newSquare
}
let myA = createSquare({color: 'red', width: 1000})
console.log(myA)

// 只读属性
interface Point {
    readonly x: number;
    readonly y: number;
}
let p1: Point = {x: 10, y: 20}
console.log(p1);
// p1.x = 5 // 错误

let a: number[] = [1, 2, 3]
let ro: ReadonlyArray<number> = a

// 函数类型
interface SearchFn {
    (source: string, sub: string): boolean
}
let mySearch: SearchFn
// 对于函数类型检查来说,函数的参数名不需要与接口里定义的名字相匹配
mySearch = function(src: string, sub: string) {
    let res = src.search(sub)
    return res > -1
}