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()

浙公网安备 33010602011771号