看了一下ts,感觉就是翻版java,我怀疑是后端为了卷前端造出来的,anyway,大概看了下基础,感觉对js 理解有帮助,同事说,万物皆接口
类型
// 布尔值
let flag:boolean=true
let a:number=123
let str:string = "xxx"
let arr:string[] = ['a', 'b']
let arr:Array<number> = [1,2,3]
// 元组
let arr:[string, number, boolean] = ['a', 1, false]
// 枚举 定义标识符
enum Flag {
success = 1
error = -1
}
var f:Flag = Flag.success
// any js 获取dom 元素,修改属性
// undfined null
方法
// void ts中没有任何类型,用于定义方法没有返回值
function run():void{
console.log('run')
}
// never 其他类型(null,undefined)的子类型,从不会出现的值,
// function
function run():string{
return 'run'
}
let fun2 = function():number{
return 123
}
// ?表示可选参数
let fun = function(name:string, age?:number, grade:string='女'):string{
return `${name}:${age}`
}
类
-
类
// 类 class Person { name:string constructor(n:string) { // 实例化类的时候触发的方法 this.name = n } run():void { alert(this.name) } } var p = new Person('zs') p.run()
-
类继承
//类继承 class Web extends Person{ constructor(name:string){ super(name) // 子类中执行父类的构造函数 } } var w = new web('ls') w.run()
-
类修饰符
// 类 修饰符: // public:公有, 类、子类、类外面都可以访问--默认公有 // protected:保护,类、子类里可访问,类外面不可访问 // private:私有,类里可访问,子类、类外都不可访问 class Person { protected name:string static sex:string = '女' constructor(n:string) { this.name = n } run():void { // 实例方法 alert(this.name) } static print() { // 静态方法,不能访问类属性,只能访问静态属性 console.log(this.name) // 报错 console.log(this.sex) // 🉑️ } }
-
多态
// 多态 父类定义方法不实现,让继承子类实现,每个子类都有不同的表现class zs extend Person{ constructor(n:string) { super(n) } run():void { // 重新实现的父类方法 alert('zs') } }
-
抽象类
// 抽象类,提供其他类继承的基类,不能直接被实例化 -- 定义标准 // absctract 定义的抽象类、抽象方法,不包含具体实现且必须在派生类中实现 // 抽象方法只能出现在抽象类中 abstract class Animal { name:string constructor(name:string) { this.name = name } abstract eat():any }
// let d = new Animal() 🙅 抽象类不可以被实例化 class Dog extends Animal { constructor(name:any) { super(name) } eat(){ console.log(this.name + '吃粮食') } }
let d = new Dog('hello') d.eat()
接口
接口是规范的定义,定义行为和动作规范
-
属性接口
// 属性接口
interface FullName{ first:string; // 注意 ; 结束 second?:string; // 可选属性 }
function printName(name:FullName) { console.log(name.first+name.second) }
var obj={ age:20, first: 'zhang', second: '三' }
printName(obj)
-
函数类型接口
// 函数类型接口:对方法传入的参数、返回值进行约束 //加密函数类型接口
interface encrypt{ (key:string, value:string):string; }
var md5:encrypt = function(key:string, value:string):string{ return key+value }
-
可索引接口:数组、对象的约束,不常用
interface UserArr { [index:number]:string }
var arr:UserArr = ['a', 'b']
interface UserObj { [index:string]:string } var arr:UserObj={name: 'zs'} //基本用不到,只有这一种情况
-
类 类型接口:对类的约束,跟抽象类有点相似
interface Animal { name: string; eat(str:string):void; }
class Dog implements Animal{ name:string; constructor(name:string){ this.name = name } eat(){ console.log(this.name + '吃粮食') }
}
-
接口扩展,接口可以继承接口
interface Animal{ eat():void; }
interface Person extends Animal{ work():void; }
class Web implements Person{ public name:string; constructor(name:string) { this.name = name } eat() { console.log(this.name + '吃杂粮') } work() { console.log(this.name+ '工作') } }
泛型
解决类、接口、方法的复用性,以及对不特定数据类型的支持。一个组件可以支持多种类型的数据,用户可以根据自己的数据类型来使用组件
function getData<T>(value:T):T{
return 'hahha'
}
getData<number>(123)
// 泛型类
class MinClass<T>{
public list:T[] = []
add(num:T):void {
this.list.push(num)
}
min():T{
var minNum = this.list[0]
for(var i=0; i<this.list.length; i++) {
if(minNum > this.list[i]) {
minNum = this.list[i]
}
}
return minNum
}
}
//泛型接口
interface ConfigFn{
<T>(value:T):T;
}
var getData:ConfigFn = funciton<T>(value:T):T{
retrun value
}
泛类:泛型可以避免重复的代码以及对不特定数据类型的支持(类型校验)
class User {
username: string | undefined,
password: string | undefined
}
//class MysqlDb {
add(user:User):boollean{
return true;
}
//}
// 泛类,防止重复写
class MysqlDb<T> {
add(info:T):boollean{
return true;
}
}
var u = new User()
u.username = 'zs'
u.password = '123'
var Db = new MysqlDb<User >()
Db.add(u)
模块:外部模块,用于代码服用,一个模块里由多个命名空间
命名空间:内部模块,用于组织代码、避免命名冲突
namespace A {}
装饰器:一个方法,可以扩展类、属性、方法、参数的功能
分类:类装饰器、属性装饰器、方法装饰器、参数装饰器
写法:普通装饰器(无法传参)、装饰器工厂(可传参)
执行顺序:
- 属性>方法>方法参数>类
- 若有多个同样的装饰器,先执行后面的
类装饰器
类声明之前声明,用于类构造函数,监视、修改、替换类定义
类的构造函数是类装饰器的唯一参数
function logClass(params:any) {
console.log(params) // httpclient 类
params.prototype.apiUrl = 'xxxx'
}
// 普通装饰器
@logClass
class HttpClient{
constructor(){}
getData(){}
}
var http = new HttpClient()
//装饰器工厂
function logClass(params:string) {
return function(target:any) {
console.log(target) // httpclient 类
console.log(params)
target.prototype.apiUrl = params
}
}
@logClass('hello')
class HttpClient{
constructor(){}
getData(){}
}
属性装饰器
在运行的时当作函数被调用,传入下列2个参数
-
对于静态成员来说是类的构造函数,对于实例成员是原型对象
-
成员的名字
function logProperty(params:any) { return function(target:any, attr:any) { console.log(target) console.log(attr) target[attr] = params } }
class HttpClient{ @logProperty('xxxx') public url:any | undefined constructor() {} getData() { console.log(this.url) } }
方法装饰器
应用到方法的属性描述符上,可用来监视、修改,代替方法定义
function get(params:any) {
return function(target:any, methodName:any, desc:any) {
console.log(target)
console.log(methodName)
console.log(desc)
console.log(desc.value) // 方法
}
}
class HttpClient{
public url:any | undefined;
constructor(){}
@get('xxxx')
getData(){
console.log(this.url)
}
}
方法参数装饰器
会在运行时当作函数被调用,可以使用参数装饰器为类的原型添加一些元素数据,传入下列3个参数
-
对静态成员来说是类的构造函数,对实力成员是类的原型对象
-
方法的名字
-
参数在函数参数列表中的索引
function logParams(params:any) { retrun function(target:any, methodName:any,paramsIndex: any) { console.log(params) console.log(target) console.log(methodName) console.log(paramsIndex) } }
class HttpClient{ public url: any | undefined; constructor(){} getData(@logParams('xxx') uuid:any) {
}}
var http:any = new HttpClient() http.getData(1234567)