对ts的基本认识
A ts是未来的发展语言,为什么这么说,因为Google的Angular、vue源码、React、微信小程序都开始采用这个语言,这足以看出这个语言的重要性
ts的特点:类型系统和完整的面向对象编程,关于这2点我只有后续的学习再去体会了。
ts的包含了es567,可见ts是js的超集,js学的好,ts可能上手更快吧🍿
搭建ts的环境
ts新增的类型和面向对象的方式,浏览器和node.js是不会识别和执行的,因为浏览器和node.js只能运行js代码
这个时候就需要一个工具将ts转成浏览器和node.js能识别的代码,这个工具就是ts环境
所以需要全局安装
npm install -g typescript
检验安装
tsc -v
浏览器和node.js 运行ts程序
浏览器
// 01-hello.ts
function sayHi(name: string): void {
console.log('hi' + name)
}
let myName: string = 'kvon'
sayHi(myName)
新建一个html文件,引入ts文件,发现控制台会报错,是无法处理这个ts中的代码的,所以需要翻译一步
tsc 01-hello.ts
这个时候会自动生成一个js文件
// 01-hello.js
function sayHi(name) {
console.log('hi' + name);
}
var myName = 'kvon';
sayHi(myName);
这个时候我们html文件引入的是js文件,而不是ts,控制台也按照预期输出了
node.js
在浏览器运行ts的操作,已经完成了,接下来处理在node.js环境下运行ts
直接运行node 01-hello.ts 是会报错的
但是每次使用tsc去编译就很麻烦。这个时候我们就需要一个插件可以帮我们自动翻译
npm i -g ts-node
之后直接运行ts-node 01-hello.ts
就可以在控制台输出值了
但是我在操作这步的时候,遇到了bug 报错
Error: Cannot find module '@types/node/package.json........'
解决方案:
npm install -g tslib @types/node
学习文件目录:
ts基础知识
ts变量
js:声明一个变量,可以给变量赋值成任何一个数据类型
let a;
a = 18;
a = 20;
a = 'kvon'
ts:声明一个变量时,必须指定变量的数据类型,而且只能赋值给变量相应的数据类型
let age:number;
age = 18;
age = 20;
age = "kvon"; // 提示报错:不能将类型“string”分配给类型“number”。
ts数据类型
null和undefined
ts:ts兼容js所有的数据类型,这里特别提一下null和undefined。 null和undefined在ts中也是2个数据类型,表示的含义如下:
undefined表示声明了一个变量,但是没有初始化、
null 表示定义一个空对象
变量是undefined数据类型,那么只能赋值undefined
变量是null数据类型,那么只能赋值null
let a1: undefined = undefined
// a1 = 18 // 不能将类型“18”分配给类型“undefined”。
let a2: null = null
// a2 = 'kvon' //不能将类型“"kvon"”分配给类型“null”。
这里有一句话:undefined和null是其他类型的子类型,所以可以给其他数据类型赋值undefined和null
下面代码期待打出undefined,这也符合我之前的知识,没有赋值的变量,值是undefined,但是事实是提示报错了
let a3: number
console.log(a3) // undefined
查了资料,需要修改vscode的配置:"strictNullChecks": false, 设置为false。
但是官网是推荐把strictNullChecks设置成true的,这里知道这个点就行了。
尝试着做了一下,网上给的答案是在setting.json文件中设置,我照做了,并且重新启动了vscode,但是还是报错,没有实现,我不知道为什么?
"js/ts.implicitProjectConfig.strictNullChecks": false
数组
js和ts的数组还是有很大的不同
js:不限制数组内数据的类型
let arr = [1, 'kvon', [], {}]
console.log(arr) // [ 1, 'kvon', [], {} ]
ts:数组中的数据必须是统一类型
let arrEnum: string[] = ['kovn', 'jack', 'tom']
let arrEnum: string[] = ['kovn', 'jack', 'tom',18] // 会报错
let arrayT: Array<number> = [1, 2, 3, 4, 5.6] // 数组的泛型
ts数组两种的写法
声明 数组名 :数据类型[] = [......]
声明 数组名:Array<数组类型> = [.....]
元组
元组是必须指定长度和每一个元素数据类型的特殊数组
let tup1:[string,number,boolean] = ['kvon讨厌~~',18,false]
console.log(tup1[0]); // kvon讨厌~~
console.log(tup1.length); // 3
💥说明:ts不支持 0是false 1是true的
💡思考:为什么需要元组?
因为数组只能存储相同类型的数据,但是我们有些业务需求是要存储不一样的数据类型的。所以就会有了元组的概念
枚举
枚举可以解决一类数据类型。所以ts产生了枚举类型,主要由枚举项和枚举值组成
创建枚举值
let Gender = {
Boy: 1,
Girl: 2,
unknown: 3,
}
console.log(Gender.Boy) // 1
console.log(Gender.Girl) // 2
console.log(Gender.unknown) // 3
使用枚举值
let userSex = Gender.Boy
console.log(userSex) // 1
if (userSex === Gender.Boy) {
console.log('相等~~')
} else {
console.log(userSex)
}
联合类型
因为有一个变量可以是多个数据类型的需求,或者说有时候并不能完全指定变量的类型,所以出现了联合类型
定义 变量名:数据类型|数据类型|数据类型...
let name: string | number
name = 'kvon'
console.log(name) // kvon
name = 18
console.log(name) // 18
console.log(typeof name) // number
any
指定一个变量的数据类型可以是任何类型
比如通过DOM获取用户输入的数据类型
let inputVal: any = document.getElementById('id')
void
函数如果有返回值必须指定返回值类型,如果没有返回值类型,返回void
定义函数
function test(): string {
return 'my name is kvon~~'
}
function test2(): void {
console.log('我的返回值是空')
}
调用函数
// 调用
let res:string = test()
console.log(res)
test2()
never
如果函数抛出异常或者是一个无线循环的函数,函数的返回值就可以定义为never类型
ts函数
函数必须有返回值,如果没有返回值,返回void
// 1.函数返回值
function sayHello(): string {
return '你好,这个世界'
}
let val: string = sayHello()
console.log(val)
// 2.函数参数
function jumpSan(cityName: string): void {
console.log('你好,请问你想跳去哪里呀')
console.log(`你好,狗子,我想去${cityName}`)
}
jumpSan('p城')
函数:实参和形参类型必须一致,实参和形参数量必须一致
可选参数
可选参数在形参后面添加?
function gun(gunName: string, count?: number): void {
console.log(`我要去p城买【${gunName}】总计买【${count ? count : 1}】把`)
}
gun('k971',10)
gun('k917')
默认值
默认值在一定程度上就是代表了可选参数的意义,所以默认值是更常用的
function gunCount(gunName: string = 'k917', count: number = 1): void {
console.log(`我要去p城买【${gunName}】总计买【${count ? count : 1}】把`)
}
// 不传参
gunCount() // gunCount('k917',1)
// 传前面一个参数
gunCount('k111') // gunCount('k111',1)
// 传2个参数
gunCount('k520', 10) // gunCount('k520', 10)
// 传后面一个参数
gunCount(undefined,12) // gunCount('k917',12)
剩余参数
剩余参数和js的argument的概念非常相似了,而且剩余参数就是一个指定数据类型的数组,且有且只有一个,且放在函数参数最后
利用剩余参数的概念实现一个求和
function add(a: number, b: number, ...rest: number[]): void {
let ress = a + b
for (let i: number of rest) {
ress += i
}
console.log('结果是:' + ress)
}
add(1, 2)
add(1, 2, 3, 4, 5, 6, 7)
类
在js中想要批量创建对象,采用的是构造函数+new的方式
// 构造函数实现变量
function City (name, level) {
this.cname = name
this.clevel = level
}
// 原型实现方法
City.prototype.about = function () {
console.log(`欢迎来到${this.cname},这个城的危险指数是${this.clevel}~~`)
}
let Kcity = new City('Pp城',10)
Kcity.about()
在ts中创建对象,提供的是一个新的数据结构:类
class City {
// 成员变量
cName: string
clevel: number
// 构造函数
constructor(name: string, level: number) {
this.cName = name
this.clevel = level
}
// 成员方法
about() {
console.log(`欢迎来到${this.cName},这个城的危险指数是${this.clevel}~~`)
}
}
let city = new City('P城', 3)
city.about()
从代码层面来看,ts实现的类更加的优雅,不需要去操作原型,写法更加简洁明了。
案例1:回顾localStorage
localStorage 的基本方法
localStorage.setItem('key','value');
localStorage.getItem('key');
localStorage.removeItem('key');
localStorage.clear();
localStorage只能存储字符串,对于对象的存储需要特殊处理
存对象
let obj1: string = JSON.stringify(obj)
localStorage.setItem('obj1', obj1)
取对象
let str1 = localStorage.getItem('obj1')
let obj = JSON.parse(str1)
实现一个基础的localStorage操作
// html
<body>
k_e_y:<input type="text" id="txtkey" /><br />
value:<input type="text" id="txtval" /><br />
<input type="button" value="存数据" id="saveBtn" />
<input type="button" value="取数据" id="getBtn" />
<input type="button" value="删除数据" id="delBtn" />
<input type="button" value="清空数据" id="clBtn" /><br />
<input type="button" value="存对象" id="saveObj" />
<input type="button" value="取对象" id="getObj" />
<script src="../js/09_localstorage/localstroage.js"></script>
</body>
💥注意:js的文件引入要放在body的底部,不然获取不到dom元素
获取所有的dom元素
// 获取定义的dom对象
let txtkey: any = document.getElementById('txtkey')
let txtvalue: any = document.getElementById('txtval')
let saveBtn: any = document.getElementById('saveBtn')
let getBtn: any = document.getElementById('getBtn')
let delBtn: any = document.getElementById('delBtn')
let clBtn: any = document.getElementById('clBtn')
let saveObj: any = document.getElementById('saveObj')
let getObj: any = document.getElementById('getObj')
存数据
// 存数据
saveBtn.onclick = function () {
let key = txtkey.value
let val = txtvalue.value
if (key && val) {
localStorage.setItem(key, val)
window.alert('存数据成功~~')
txtkey.value = ''
txtvalue.value = ''
} else {
window.alert('请输入数据!!')
}
}
取数据
// 取数据
getBtn.onclick = function () {
let key = txtkey.value
let val = localStorage.getItem(key)
if (val) {
window.alert(`取出的数据是:${val}`)
txtkey.value = ''
txtvalue.value = ''
} else {
window.alert('你取的数据不存在')
}
}
删除数据
// 删除数据
delBtn.onclick = function () {
let key = txtkey.value
let v = localStorage.getItem(key)
if (v) {
localStorage.removeItem(key)
window.alert('你的数据已经删除!')
txtkey.value = ''
txtvalue.value = ''
} else {
window.alert('你删除的数据根本不存在!!')
}
}
清除数据
// 清空数据
clBtn.onclick = function () {
let len: number = window.localStorage.length
if (len) {
localStorage.clear()
window.alert('所有数据都删除了!!!')
txtkey.value = ''
txtvalue.value = ''
} else {
window.alert('存储空间是空的!!!')
}
}
存对象
//存对象
saveObj.onclick = function () {
let obj: Object = {
name: 'tom',
age: 18,
hobbey: '帅哥~~',
}
let str: string = JSON.stringify(obj)
localStorage.setItem('obj', str)
window.alert('存储对象~~')
}
取对象
// 取对象
getObj.onclick = function () {
let str: string | null = localStorage.getItem('obj')
let obj = JSON.parse(str as string)
console.log(obj)
}
案例2:ts封装一个DataHelper类
业务需求:
能够通过使用ts+localStorage实现新增评论、删除评论、获取评论的功能!
代码太长了。而且有很多值得注意的细节,所以我就放到代码编辑器里,而且只能引入js,我是ts写的,所以我就放了编译后的文件
ts代码放到下面这个编辑器了