函数
函数是 JavaScript 应用程序的基础,它帮助你实现抽象层,模拟类,信息隐藏和模块。在 TypeScript 里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义行为的地方。TypeScript 为 JavaScript 函数添加了额外的功能,让我们可以更容易地使用。
// 封装了一些重复使用的代码,在需要的时候直接调用即可
(()=>{
// js书写方式,ts也可以书写
// 函数声明,命名函数
// function add(x, y){
// return x + y
// }
// 函数表达式,匿名函数
// const add2 = function (x, y){
// return x + y
// }
// ts书写方式
// 函数声明,命名函数
// 函数中的x,y的参数的类型都是string,小括号后面的:string代表的是该函数的返回值也是string类型的
function add(x:string, y:string):string{
return x + y
}
const result1:string = add('10','20')
console.log(result1)
// 函数表达式,匿名函数
// 函数中的x,y的参数的类型都是number,小括号后面的:number代表的是该函数的返回值也是number类型的
const add2 = function (x:number, y:number):number{
return x + y
}
console.log(add2(10,20))
// 函数的完整写法
// add3===>变量名===>函数add3
// (x:number,y:number) => number 当前这个函数的类型
// function (x:number,y:number):number{return x + y} 就相当于符合上面的这个函数类型的值
const add3:(x:number,y:number) => number = function (x:number,y:number):number{
return x + y
}
console.log(add3(10,100))
})()
可选参数和默认参数
可选参数:函数在声明的时候,内部的参数使用了?进行修饰,那么就表示该参数可以传入也可以不传入,叫做可选参数
默认参数:函数在声明的时候,内部的参数有自己的默认值,此时的这个参数就可以叫默认参数
(()=>{
const getFullName = function(firstName:string='爱蜜莉雅',lastName?:string):string{
// 判断名字是否传入了
if(lastName){
return firstName + '-' lastName
}else{
return firstName
}
}
// 什么也不传
console.log(getFullName())
// 只传入姓氏
console.log(getFullName('诸葛'))
// 传入姓氏和名字
console.log(getFullName('樱岛','麻衣'))
})()
剩余参数(rest参数)
是放在函数声明的时候所有的参数的最后
(()=>{
// args:string[] 剩余的参数,放在了一个字符串的数组中,args里面
function showMsg(str:string,...args:string[]){
console.log(str) // a
console.log(args) // b c d e
}
showMsg('a','b','c','d','e')
})()
函数重载
函数名字相同,函数的参数及个数不同
(()=>{
// 函数重载
function add(x:string, y:string):string
function add(x:number, y:number):number
// 函数声明
function add(x:string | number ,y:string | number):string | number{
if(typeof x === 'string' && typeof y === 'string'){
return x + y
}else if(typeof x === 'number' && typeof y === 'number'){
return x + y
}
}
console.log(add('爱蜜莉雅','糖糖'))
console.log(add(10,100))
// 非法的,报红
// console.log(add('真好',10))
// console.log(add(100,'棒棒的'))
})()
泛型
指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。
(()=>{
// 传入两个参数,第一个参数是数据,第二个参数是数量,函数的作用:根据数量产生对应个数的数据,存放在一个数组中
function getArr1(value:number,count:number):number[]{
const arr:number[] = []
for(let i = 0, i < count, i++){
arr.push(value)
}
return arr
}
const arr1 = getArr1(100.123,3)
console.log(arr1)
// 同上,类型是string
function getArr2(value:string,count:number):string[]{
const arr:string[] = []
for(let i = 0, i < count, i++){
arr.push(value)
}
return arr
}
const arr2 = getArr2('abc',3)
console.log(arr2)
// 可以传入任意类型,返回出来的是任意类型的数组
function getArr3(value:any,count:number):any[]{
const arr:any[] = []
for(let i = 0, i < count, i++){
arr.push(value)
}
return arr
}
const arr3 = getArr3('abc',3)
const arr4 = getArr3(100.123,3)
console.log(arr3)
console.log(arr4)
// 没有任何的智能提示信息
console.log(arr3[0].split(''))
console.log(arr4[0].toFixed(2))
function getArr4<T>(value:T,count:number):T[]{
// const arr:T[] = [] 或者
const arr:Array<T> = []
for(let i = 0, i < count, i++){
arr.push(value)
}
return arr
}
const arr5 = getArr4<number>(200.12345,5)
const arr6 = getArr4<string>('abc',5)
console.log(arr5)
console.log(arr6)
// 有智能提示信息
console.log(arr5[0].toFixed(2))
console.log(arr6[0].split(''))
})()
泛型的多个参数
一个函数可以定义多个泛型参数
(()=>{
function getMsg<K,V>(value1:K,value2:V):[K,V]{
reuturn [value1,value2]
}
const arr1 = getMsg<string,number>('jack',100.123)
console.log(arr1[0].split(''))
console.log(arr1[1].toFixed(2))
})()
泛型接口
在定义接口时, 为接口中的属性或方法定义泛型类型
在使用接口时, 再指定具体的泛型类型
(() => {
// 定义一个泛型接口
interface IBaseCRUD<T> {
data: Array<T>
// t函数参数 :T参数类型 =>T返回值
add: (t: T) => T
getUserId: (id: number) => T
}
// 定义一个用户信息的类
class User {
id?: number
name: string
age: number
constructor(name: string,age: number) {
this.name = name
this.age = age
}
}
// 定义一个类,针对用户的信息对象进行增加及查询的操作
class UserCRUD implements IBaseCRUD<User>{
// 用来保存多个User类型的用户信息对象
data: Array<User> = []
// 用来存储用户信息对象
add(user: User): User {
user.id = Date.now() + Math.random()
// 把用户信息对象添加到data数组
this.data.push(user)
return user
}
// 根据id查询指定的用户信息对象
getUserId(id: number): User {
return this.data.find(user => user.id === id)
}
}
// 实例化
const userCRUD: UserCRUD = new UserCRUD()
// 调用添加数据方法
userCRUD.add(new User('jack',20))
userCRUD.add(new User('tom',21))
const { id } = userCRUD.add(new User('tom',21))
console.log(userCRUD.data)
// 根据id查询用户信息对象数据
const user = userCRUD.getUserId(id)
console.log(user)
})()
泛型类
在定义类时, 为类中的属性或方法定义泛型类型 在创建类的实例时, 再指定特定的泛型类型
(() => {
// 定义一个泛型类
class GenericNumber<T> {
// 默认的属性值的类型是泛型类
defalutValue: T
add: (x: T,y: T) => T
}
// 在实例化对象的时候在确定泛型的类型
const g1: GenericNumber<number> = new GenericNumber<number>()
// 设置属性值
g1.defalutValue = 100
// 相加的方法
g1.add = function (x,y) {
return x + y
}
console.log(g1.add(10,100))
const g2: GenericNumber<string> = new GenericNumber<string>()
g2.defalutValue = 'abc'
g2.add = function (x,y) {
return x + y
}
console.log(g2.add('爱蜜莉雅','糖糖'))
})()
泛型约束
如果我们直接对一个泛型参数取 length
属性, 会报错, 因为这个泛型根本就不知道它有这个属性
(() => {
// 定义一个接口用来约束将来的某个类型中必须要有length这个属性
interface ILength {
// 接口中有一个属性length
length: number
}
function getLength<T extends ILength>(x: T): number {
return x.length
}
console.log(getLength<string>('爱蜜莉雅糖糖'));
})()
声明文件
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能
什么是声明语句
假如我们想使用第三方库 jQuery,一种常见的方式是在 html 中通过 <script>
标签引入 jQuery
,然后就可以使用全局变量 $
或 jQuery
了。
但是在 ts 中,编译器并不知道 $ 或 jQuery 是什么东西
安装jQuery
npm install jquery
/*
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。
声明语句: 如果需要ts对新的语法进行检查, 需要要加载了对应的类型说明代码
declare var jQuery: (selector: string) => any;
声明文件: 把声明语句放到一个单独的文件(jQuery.d.ts)中, ts会自动解析到项目中所有声明文件
*/
下载声明文件
npm install @types/jquery --save-dev
创建一个jQuery.d.ts文件
declare var jQuery: (selector: string) => any
// 引入第三方jQuery库
import jQuery from 'jquery'
// 使用jQuery
jQuery('选择器')
内置对象
JavaScript 中有很多内置对象,它们可以直接在 TypeScript 中当做定义好了的类型。
内置对象是指根据标准在全局作用域(Global)上存在的对象。这里的标准是指 ECMAScript 和其他环境(比如 DOM)的标准。
(() => {
/* 1. ECMAScript 的内置对象 */
let b: Boolean = new Boolean(1)
let n: Number = new Number(true)
let s: String = new String('abc')
let d: Date = new Date()
let r: RegExp = /^1/
let e: Error = new Error('error message')
b = true
// let bb: boolean = new Boolean(2) // error
/*BOM 和 DOM 的内置对象 */
const div: HTMLElement = document.getElementById('test')
const divs: NodeList = document.querySelectorAll('div')
document.addEventListener('click',(event: MouseEvent) => {
console.dir(event.target)
})
const fragment: DocumentFragment = document.createDocumentFragment()
})()
总结:
TypeScript 在社区的流行度越来越高,它非常适用于一些大型项目,也非常适用于一些基础库,极大地帮助我们提升了开发效率和体验。