• Typescript模块化/命名空间/装饰器


    模块的概念(官方)

      关于术语的一点说明:请务必注意一点,Typescript里面发生变化,“内部模块”现在成为“命名空间”。“外部模块”现在简称为“模块”,模块在其自身的作用域里执行,而不是在全局作用域里;这意味着定义在一个模块里的变量,函数,类等在模块外部是不可见的,除非你明确使用export形式导出,相反,如果想使用其他模块的变量,函数,类等,你必须要导入它们,可以使用import形式

    模块的理解:

      我们可以把一些公用的功能单独抽离成一个文件作为模块,模块里面的变量、函数、类等默认是私有的,如果我们要在外部访问模块里面的数据,我们需要通过export暴露里面的数据(变量、函数、类等),暴露后我们通过import引入模块可以使用模块里面的数据。

    • 项目同级创建一个modules文件,写一个db.ts
      var dbUrl = 'xxx'
      
      export function getData(){
          console.log("获取数据库数据")
          return [
              {
                  title:'1'
              },
              {
                  title:'2'
              }
          ]
      }
      
      export {dbUrl} 
    • 修改index.ts文件
      import {getData,dbUrl as Url} from './modules/db'
      
      getData();
      console.log(Url)  

    命名空间

    为了防止变量名等命名重复问题,这里使用命名空间区分。

    namespace A{  // 创建一个命名空间
        interface Animal {
            name:string;
            eat():void;
        }
    
        export class Dog implements Animal {  // 这里也需要导出一个类
            name:string; 
            constructor(name:string){
                this.name = name;
            }
            eat(){
                console.log(this.name+"吃饭");
            }
        }
    }
    
    var  d = new A.Dog("小黑");
    d.eat() 
    // 当出现几个开发的时候,命名重复,这里则通过命名空间区分  

    如果想把命名空间做成模块化,需要如下使用

    // modules文件的name.ts文件
    export namespace A{  // 创建一个命名空间
        interface Animal {
            name:string;
            eat():void;
        }
    
        export class Dog implements Animal {  // 这里也需要导出一个类
            name:string; 
            constructor(name:string){
                this.name = name;
            }
            eat(){
                console.log(this.name+"吃饭");
            }
        }
    }
    
    
    // 使用是的index.ts
    import {A} from './modules/name'
    var a = A.Dog("xxx")
    a.eat()
    

      

    装饰器

    装饰器是一种特殊类型的声明,它能够被附加到类声明、方法、属性或参数上,可以修改类的行为,通俗来将装饰器就是一个方法注入到类、方法、属性参数上的扩展功能,常见的装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器;

    常见的写法:普通装饰器(无法传参)、装饰器工厂(可传参数)

    类装饰器:声明之前,用于类构造函数,可以监视、修改或替换类定义

    //方法1:普通类装饰器
    function logClass(params:any) {  // 需要写一个参数接受类名
        console.log(params)  // params就是当前类
    
        // 扩展类属性
        params.prototype.apiUrl = 'xxxx'
        // 扩展方法
        params.prototype.run= function(){
            console.log("running...")
        }
    }
    
    @logClass
    class HttpClient {
        constructor() {
    
        }
    
        getData() {
    
        }
    }
    
    var http:any = new HttpClient();
    console.log(http.apiUrl)
    http.run();
    
    
    //方法2: 装饰器工厂(可传参)
    function logClass1(params:string){
        return function(target:any) {
            console.log(target)
            console.log(params)  // hello
    
            target.prototype.apiUrl = 'www'
        }
    }
    
    @logClass1('hello')  // 需要传入参数
    class HttpClient1 {
        constructor() {
    
        }
    
        getData() {
    
        }
    }
    
    var h:any = new HttpClient1();
    console.log(h.apiUrl)
    
    // 类装饰器: 会在运行是当作函数调用,类的构造函数作为其唯一的参数,如果类装饰器返回一个值,它会
    // 使用提供的构造函数替换类的声明
     
    function logClass2 (target:any){
        console.log(target);
        return class extends target{  // 重载类装饰器
            apiUrl:any = "我是重载后的url"  // 这样就会重载之前的属性
            getData(){
                this.apiUrl = this.apiUrl+'xxx'
                console.log(this.apiUrl)
            }
        }
    
    }
    
    @logClass2
    class HttpClient2 {
        public apiUrl:string|undefined;
    
        constructor() {
            this.apiUrl = '我是构造函数里面的apiUrl'
        }
    
        getData() {
            console.log(this.apiUrl)
        }
    }
    
    var h1 = new HttpClient2();
    h1.getData();
    
    
    // 类装饰器
    function logClass3(params:string){
        return function(target:any) {
            console.log(target)
            console.log(params)  // hello
    
            target.prototype.apiUrl = 'www'
        }
    }
    // 属性装饰器
    function logProperty(params:any){
        return function(target:any,attr:any){
            console.log(target) // 类原型对象
            console.log(attr)  // 类属性
            target[attr] = params
        }
    }
    
    @logClass3('xxxx')  // 需要传入参数
    class HttpClient3 {
        @logProperty("http:www.baidu.com")
        public url:any |undefined
        constructor() {
    
        }
    
        getData() {
            console.log(this.url)
        }
    }
    
    var h2 = new HttpClient3()
    h2.getData()
    

      

  • 相关阅读:
    AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式
    Java中List集合去除重复数据的方法
    java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp区别和总结
    Spring 中配置log4j日志功能
    log4j配置文件加载方式
    程序中使用log4J打印信息的两种方式
    elasticsearch常用命令
    接私活必备的10个开源项目??
    初识Elasticsearch
    常用在线工具
  • 原文地址:https://www.cnblogs.com/double-W/p/12879263.html
Copyright © 2020-2023  润新知