it营Typescript学习笔记02(基础完结)模块,命名空间,装饰器

1、模块的概念

内部模块类似于命名空间,外部模块才简称为模块
模块在自身作用域内起作用,不能在全局作用域中使用(被导出是例外)
模块内的变量,函数,类在模块外不可见,可以通过export导出。然后在其他地方使用import导入

因此
可以把公共功能抽离成一个文件作为模块
模块内的变量,函数,类等默认是私有的,并通过export向外暴露,暴露后通过import导入。

1、创建模块文件db.ts

export let dbURL = 'xxxxx';
//获取数据库数据
export function getData(): any[] {
  console.log('获取数据库的数据');
  return [
    { title: 'xxtitlexx' },
    { title: 'xxtitlexx' },
  ];
}

export function save(): void { 
  console.log('保存数据成功');
  
}

2、导入并使用模块文件db.ts
index.ts

import { getData,save,dbURL } from './modules/db'
const myarr = getData()
save();
console.log(myarr);

3、在node环境下运行
在浏览器中无法支持,需要在node环境下执行编译后的index.js

node index.js
2、模块的导出
  • 在暴露过程中可以集中暴露,直接以对象形式进行暴露,上例模块部分可以写成
let dbURL = 'xxxxx';
//获取数据库数据
function getData(): any[] {
  console.log('获取数据库的数据');
  return [
    { title: 'xxtitlexx' },
    { title: 'xxtitlexx' },
  ];
}

function save(): void { 
  console.log('保存数据成功');
  
}
export { dbURL,getData,save}
  • export的时候也可以使用as关键字,未某个导出的方法或属性起别名
export { dbURL,getData as get,save}

在import的时候则只能使用别名,而不能使用原名称

  • 只有一个方法的时候可以使用默认导出export default
 export default function myfun(){
 }


在已经写好方法体的情况下

 export default  myfun
 import myfun from 'xxxxx'

注意,export default在单个模块中只能使用一次

3、使用命名空间

命名空间:内部模块,主要用于组织代码,避免命名冲突
模块:ts的外部模块的简称,侧重代码的复用,一个模块里可能有多个命名空间
大致与java的命名空间一致
命名空间内的变量、函数、类等要使用export导出

namespace A { 
  export class Dog { }
}
namespace B { 
  export class Dog { 
  }
}

let d1 = new A.Dog();
let c1 = new B.Dog();
4、导出、导入命名空间

1、创建命名空间文件db.ts

export namespace A { 
  export class Dog { 
    name: string;
    constructor(name:string) {
      this.name = name;
      
    }
    sing() { 
      console.log(`${this.name} is singing a song`);
      
    }
  }
}
export namespace B { 
  export class Dog { 
  }
}

2、导入命名空间

import { A,B } from './modules/db'

let d1 = new A.Dog('zhagnsan');
let c1 = new B.Dog();
d1.sing()

5、装饰器
  • 装饰器是一种特殊类型的声明,能够被附加到类声明、方法、属性或参数上,可以修改类的行为
  • 通俗讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
  • 常见的装饰器有:类装饰器、属性装饰器,方法装饰器、参数装饰器
  • 装饰器的写法:普通装饰器(无法传参),装饰器工厂(可传参)
  • 装饰器是过去几年js最大的成就之一,已是es7的标准特性之类
6、类装饰器

类装饰器在类声明之前被声明(紧靠着类声明)。
类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。传入一个参数

//声明一个装饰器,和函数声明一样
function logClass(params: any) {
  console.log(params);//params就是被修饰的类
  //给被装饰的类原型进行扩展
  params.prototype.apiUrl = 'myapiurl';//扩展了原型,增加了apiUrl属性
  params.prototype.run = function () { 
    console.log('i am a method of running');
    
  }
 }

//使用@表示调用装饰器
@logClass
class HttpClient { 
  constructor(){ 

  }
  getData() { 

  }
}

@logClass
class Person{ 
  constructor() { }
  work() { }
}


let p1: any = new Person();
let h1:any = new HttpClient();
console.log(p1.apiUrl, h1.apiUrl);
p1.run();
h1.run();
7、装饰器工厂(可传参)
这里有两个参数,一个是装饰器本身的参数,接收设计者传入的参数,一个是工厂返回的函数参数,接收被装饰类
//声明一个装饰器,和函数声明一样
function logClass(params: any) {
  //返回一个函数,这里的target是从被装饰类中返回过来的参数,成为一个装饰器工厂
  return function (target: any) { 
    console.log(params);
    console.log(target);
    target.prototype.apiUrl = params;
  }
 }

//使用@表示调用装饰器
@logClass('http://www.sina.com')//表示把hello赋给了装饰器的params,把整个类赋值给了target
class HttpClient { 
  constructor(){ 

  }
  getData() { 

  }
}

let h1:any = new HttpClient();
console.log(h1.apiUrl);
8、装饰器修改类构造函数

类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明

//声明一个装饰器,和函数声明一样
function logClass(target: any) {
  console.log(target);
  //返回一个匿名类,并且继承了target类,注意要重载父类的所有属性和方法
  return class extends target { 
    //修改apiUrl,实际是是要
    apiUrl: any = '我是修改后的数据';
    getData() { 
      console.log(this.apiUrl+'---');
      
    }

  }
 }

//使用@表示调用装饰器
@logClass
class HttpClient {
  public apiUrl: string | undefined;
  constructor(){ 
    this.apiUrl = '我是构造函数里面的apiurl';
  }
  getData() { 
    console.log(this.apiUrl);
    
  }
}

let h1:any = new HttpClient();
h1.getData()
9、属性装饰器

属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
2、成员的名字

//声明一个类装饰器,和函数声明一样
function logClass(params: any) {
  //返回一个函数,这里的target是从被装饰类中返回过来的参数,成为一个装饰器工厂
  return function (target: any) { 
    target.prototype.apiUrl = params;
  }
 }
//声明一个属性装饰器
function logProperty(params: any) { 
  //返回一个函数,要接收两个参数
  return function (target: any, attr: any) { 
    console.log(target);
    console.log(attr);
    target[attr] = params;
    
  }
}
//使用@表示调用装饰器
@logClass('http://www.sina.com')//表示把hello赋给了装饰器的params,把整个类赋值给了target
class HttpClient { 
  //使用属性装饰器
  @logProperty('http://sohu.com.cn')
  public url: any | undefined;
  constructor(){ 

  }
  getData() { 
    console.log(this.url);
    
  }
}
let h1 = new HttpClient();
h1.getData()
10、方法装饰方法器(增加类属性及类方法)

会被应用到方法的属性描述符上,可以用来监视、修改或替换方法定义

方法装饰会在运行时传入下列3个参数:
1、对于静态成员来说是类的构造函数,对实例成员是类的原型对象
2、成员的名字
3、成员的属性描述符

//声明一个装饰器
function get(params: any) { 
  //返回一个函数,要接收两个参数
  return function (target: any,methodName:any,desc:any) { 
    console.log(target);
    console.log(methodName);
    console.log(desc);

    //为方法扩展属性
    target.apiUrl = 'http://www.baidu.com';
    target.run = function () { 
      console.log(' my method is run ');
      
    }
    
  }
}
class HttpClient { 
  public url: any | undefined;
  constructor(){ 

  }
  //为方法添加自定义的get装饰器
  @get('http://www.sina.com')
  getData() { 
    console.log(this.url);
    
  }
}
let h1:any  = new HttpClient();
console.log(h1.apiUrl);
h1.run();
11、方法装饰器修改类的方法
//声明一个装饰器
function get(params: any) { 
  //返回一个函数,要接收两个参数
  return function (target: any,methodName:any,desc:any) { 
    console.log(target);
    console.log(methodName);
    console.log(desc.value);

    //修改被装饰类的方法,把装饰器方法里面传入的所有参数改为string类型
    //1、保存当前的方法
    let oMethod = desc.value;
    desc.value = function (...args:any[]) { 
      args = args.map((value) => {
        return String(value);
      })
      
      console.log(args);
      oMethod.apply(this, args);
      
    }

   
    
  }
}
class HttpClient { 
  public url: any | undefined;
  constructor(){ 

  }
  //为方法添加自定义的get装饰器
  @get('http://www.sina.com')
  getData(...args:any[]) { 
    console.log(args);
    console.log('我是getData里面的方法');
    
  }
}
let h1:any  = new HttpClient();
h1.getData(123,'xxxx');
12、方法参数装饰器

参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入下列3个参数:
1、对于静态成员来说是构造函数,对于实例成员来说是原型对象
2、参数的名字
3、参数在函数参数列表中的索引。

//定义一个方法参数装饰器
function logParams(params: any) { 
  //返回一个函数,要接收3个参数,target是原型对象,methodName是方法名称,paramsIndex参数索引
  return function (target: any,methodName:any,paramsIndex:any) { 
    console.log(target);
    console.log(methodName);
    console.log(paramsIndex);
    //在装饰器上对原型添加一些数据
    target.apiUrl  = params;
    
  }
}
class HttpClient { 
  public url: any | undefined;
  constructor(){ 

  }
  //在方法的参数中调用装饰器
  getData(@logParams('xxxxx') uuid:any) { 
    console.log(uuid);
    
  }
}
let h1:any  = new HttpClient();
h1.getData(123456);
console.log(h1.apiUrl);
13、装饰器的执行顺序

属性>方法>方法参数>类装饰器
如果有同样的装饰器,则先执行后面的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值