变量和数据类型

一、什么是变量

通俗的讲:变量,是用来存储数据的容器,并且是可以变化的。
保温杯里泡枸杞 ,变量里面存数据。
枸杞难挡岁月催,杯里再换点当归:枸杞 -> 当归。

二、变量的使用

2.1 基本使用--2步走

变量的使用分为两步:1 声明变量并指定类型 2 给变量赋值。
第一步:声明变量并指定类型
let age: number;
第二步:给变量赋值
age = 18
解释:
  • 使用等号(=)来给变量 age 赋值。

2.2 简化形式

  • 声明变量的同时就赋值(变量的初始化):
let age: number = 18

变量的使用总结:

  • 变量的两种使用方式:1 先声明后赋值 2 声明的同时并赋值(推荐)
  • 第一种:先声明后赋值
// 1 声明变量并指定类型let age: number
// 2 赋值
age = 18
第二种:声明的同时并赋值(推荐)
let age: number = 18

注意:声明变量的时候要指定变量的类型。

三、 类型注解

3.1 什么是类型注解

接下来我们来看一下typescript中的类型注解。什么是类型注解呢?其实我们在前面已经用过了,我们来看一句示例代码:

let age: number = 18
代码中的 : number 就是类型注解。

3.2 作用

类型注解:是一种为变量添加类型约束的方式。
程序员 和 TS 有个约定。
// 程序员 和 TS 约定:变量 age 的类型为 number(数值类型)
let age: number = 18
重要:约定了什么类型,就只能给变量赋什么类型的值。
// × 错误演示
age = 'Hello TS'
额外说明:VSCode 中代码下方的红色波浪线表示代码报错,出 Bug 了。

四、 变量的命名规范

4.1 变量的命名规则

  • 变量名称只能出现:数字、字母、下划线(_)、美元符号($),并且不能以 数字 开头。
let age: number = 18
以下示例中变量名称是否正确:
let 2b  ×
let $name ✅
let first_name ✅
let @email × 

注意:变量名称区分大小写。
// age 和 Age 是两个不同的变量let age: number = 18let Age: number = 20

4.2 变量的命名规范

  • 代码就是程序员的脸面,规范的代码,能让人觉得专业、优雅。
  • 推荐:变量名称要有意义,顾名思义。
// 有意义,推荐
let age: number = 18
// 无意义,不推荐
let a: number = 18
  • 推荐:使用驼峰命名法(首字母小写,后面每个单词首字母大写)。
let cityName
let yourAge

总结:

  • 规则:变量名称只能出现 数字、字母、下划线(_)、美元符号($),并且不能以 数字 开头。

    注意:变量名称区分大小写。

  • 规范:变量名称要有意义,顾名思义。

    推荐:使用驼峰命名法(首字母小写,后面每个单词首字母大写)。

交换变量的值

需求:交换两个变量的值(提示:借助于第三个变量)。

// 变量1:
let num1: number = 33
// 变量2:
let num2: number = 2
// 目标:
num1 的值为2,num2 的值为33。

五、数据类型概述

平时浏览的网页中都有什么形式的内容啊? 文字、图片、视频、音乐等
问题:计算机可以正确的处理这些内容,它是如何区分这些不同形式的内容呢?
回答:数据类型。
  • lTypeScript 中的数据类型分为两大类:1 原始类型(基本数据类型) 2 对象类型(复杂数据类型)。
  •  常用的基本数据类型有 5 个:number / string / boolean / undefined / null。
// 变量 age 的类型是 number(数字类型)
let age: number = 18
// 此处的 'Hello TS' 是 string(字符串类型)console.log('Hello TS')

六、 基本数据类型

6.1 数字类型

  • 数字类型:包含整数值和浮点型(小数)值。
// 数字类型:整数
let age: number = 18
// 数字类型:小数
let score: number = 99.9
  • 当然,从另一个维度来看,也可以包含:正数和负数。
// 正数,+直接省略即可
let salary: number = +10000
// 负数
let salaryWithGirlfriend: number = -2000

6.2 字符串类型

  • 字符串:由零个或多个字符串联而成的,用来表示文本信息。
console.log('Hello TS')
console.log('') // 空字符串
  • 字符串可以使用单引号(')或双引号("),推荐:使用单引号。
'Hello TS' // 推荐
"Hello TS"
  • 字符串类型的类型注解为:string,声明变量时要添加类型注解
let food: string = '糖葫芦'

6.3 布尔类型

布尔类型,用来表示真或假。
只有两个值,分别是: true 和 false。true 表示真,false 表示假。
  • 布尔类型的类型注解为:boolean
// 真
let isStudying: boolean = true
// 假
let isPlayingGame: boolean = false

6.4 undefined、null

共同特点:只有一个值,值为类型本身。
undefined 类型的值为: undefined。
null 类型的值为:null。
// 类型注解为:
undefined let u: undefined = undefined
// 类型注解为:
null let n: null = null
  • undefined:表示声明但未赋值的变量值(找不到值)。
let u: undefined
console.log(u) // 变量u的值为 undefined

  • null:表示声明了变量并已赋值,值为 null(能找到,值就是 null)。

总结

  • TypeScript 中常用的基本数据类型有 5 个。
  • 分别是:number(数字类型)/ string(字符串类型)/ boolean(布尔类型)/ undefined /null。
    • 重点是:number / string / boolean
补充概念:这些类型的,也叫做字面量, 也就是从字面上就能看出来它是什么。
18 // 数字字面量
'保温杯里泡枸杞' // 字符串字面量true / false // 布尔字面量
undefined
null

运算符

一、运算符概述--5种

运算符也称为操作符,用来实现赋值(=)、算术运算、比较等功能的符号。
常用的运算符:
  • 算术运算符 。加减乘除呀,这我们已经知道了。
  • 赋值运算符 。赋值运算符我们在前面已经用过了,当然我们一会还会看一下。
  • 递增/递减运算符 。这个在我们学习typescript到现在还没用过,待会也会详细讲解。
  • 比较运算符 。比较就是大于呀,小于呀,我们也要做了解的。
  • 逻辑运算符

二、 算术运算符

2.1 概述

​ 算术运算符包含:加(+)、减(-)、乘(*)、除(/)。

算术运算符:它是进行算术运算时使用的符号,用于两个数值之间的计算。

// 加
console.log(1 + 2) // 3 // 减
console.log(2 - 1) // 1 // 乘
console.log(2 * 3) // 6 // 除
console.log(4 / 2) // 2

2.2 加号的其他作用

注意:+ 号,不仅可以用于加法计算,还能实现字符串拼接。 我们到代码中体验一下:

// 字符串拼接(拼串)
console.log('周杰' + '伦') // 结果为:'周杰伦' 
思考以下代码的结果:
console.log(1 + 2) // 结果为:3
console.log(1 + '2') // 结果为:'12'
console.log('1' + 2) // 结果为:'12'

规律:加号两边只要有一边是字符串,就执行字符串拼接。

2.3 加号引发的思考

​ 思考一下:既然加号可以跟字符串一起使用,那其他算术运算符(- * /)可以吗? 我们可以检验一下:

console.log(2 - '1')  // 报错:算术运算符的右侧必须是数字类型。
注意:除加号以外,其他算术运算符只应该跟数字类型一起使用

其他方式:将字符串类型转换为数字类型。

console.log(2 - +'1')
// +'1' 表示将 '1'(string) => 1(number)
// 所以,2 - +'1' ==> 2 - 1 ==> 结果为:1

  • 记住:在字符串前面添加 + 号,可以将 string 转化为 number(字符串内容为数字时才有意义)。

三、赋值运算符

赋值运算符:将等号右边的值赋值给它左边的变量,比如:等号(=)。

// 等号:将 18 赋值给左侧的变量age let age: number = 18
需求:明年老师 19 岁,让变量 age 变成 19。
age = age + 1

顺序:1 先执行等号右边的代码 2 将计算结果赋值给等号左边的变量。
除了等号(=)之外,还包括:加等(+=)、减等(-=)、乘等(*=)、除等(/=)。

age += 1

说明:其他几个(减等、乘等、除等)同理。

四、 自增和自减运算符

自增(++)运算符是 += 1 的简化形式;自减(--)运算符是 -= 1 的简化形式。
比如:让 age 的值变为 19,该如何处理?
let age: number = 18
age += 1 // 加等

更简洁的方式:++
age++

解释:age++ 会让变量 age 的值加 1。
作用:自增(++)运算符用来实现变量的值加 1;自减(--)运算符实现变量的值减 1。
注意:++--,只能让变量的值增加或减少 1

五、比较运算符

比如:考完试,拿到成绩后,比较分数。

你的100分 大于 同桌的99分
比较运算符:用于比较两个数据的值,并返回其比较的结果,结果为布尔类型。

比较运算符包含 6 个:

  • 大于(>
  • 大于等于(>=
  • 小于(<
  • 小于等于(<=
  • 等于(===
  • 不等于(!==

下面我们通过代码来理解比较运算符:

// 大于console.log(1 > 2)   // 结果为:false
// 大于等于console.log(3 >= 2)   // 结果为:true
// 小于
console.log(1 < 2)    // 结果为:true
// 小于等于console.log(3 <= 2)    // 结果为:false
// 相等
console.log(3 === 4)   // 结果为:false
// 不相等
console.log(3 !== 4)    // 结果为:true
问题1:比较运算符有什么用? 比较两个数据的值
问题2:比较结果是什么类型? 布尔类型
注意:比较运算符常用于数字类型的比较。

六、逻辑运算符

生活中,我们常用:并且、或者、不是 这样的词语,来描述一些事情。
与逻辑运算符一一对应:与(并且)、或(或者)、非(不是)。
情况一:有钱 并且 漂亮( 两个条件同时满足 )。
情况二:有钱 或者 漂亮( 只要某一个条件满足 )。
情况三:不是 男的( 取反 )。
逻辑运算符通常用于布尔类型的计算,并且结果也是布尔类型
  • 与(逻辑与),用 && 符号来表示。当 && 两边的值同时为true,结果才为true;否则,为false。
true && false // 结果为:false

示例:

// 与
console.log(2 > 1 && 2 >= 2)
// 结果为:true
  • 或(逻辑或),用 || 符号来表示。当 || 两边的值只要有一个为true,结果就为true;否则,为false。
true || false // 结果为:true

示例:

// 或
console.log(3 < 2 || 1 <= 2)
// 结果为:true
  • 非(逻辑非),符号为 !(叹号),表示取反,即:truefalse 而 falsetrue。
!true // 结果为:false

示例:

// 非
console.log(!false || false) 示例: // 结果为:true
总结:
  • 两个条件同时满足时,再执行操作,用什么? 逻辑与 &&
  • 只要有一个条件满足时,就执行操作,用什么? 逻辑或 ||
  • 逻辑非,表示什么作用? 取反 !

TypeScript 语句

一、 条件语句

1.1 概述

生活中,打开网站看电影:1 免费电影 2 Vip 电影。
播放 Vip 电影时,首先会判断是不是 Vip:
  • 如果是 Vip,就可以看完整电影;
  • 如果不是 Vip,只能试看5分钟。

1.2 if 语句

条件语句:根据判断条件的结果(真或假),来执行不同的代码,从而实现不同功能。
条件执行时,首先判断条件是否满足。
  • 如果 条件满足,就做某件事情(情况1)
  • 如果 条件不满足,就做另外一件事情(情况2)

条件语句,也叫分支语句,不同的情况就是不同的分支。
在 TypeScript 中 if 语句就是实现条件判断的。
  • if 语句的语法:
if (判断条件) {
条件满足时,要做的事情
}
解释:
  • 判断条件:布尔类型(true 或 false)。
  • 如果 判断条件 为真,就执行 要做的事情;
  • 否则,如果判断条件为假,则不执行花括号中的代码。
补充概念说明:语句,是一个完整的句子,用来使某件事情发生(或实现某个功能)。

1.3 else 语句

在 TypeScript 中 else 语句必须配合 if 语句来使用。
else 语句表示:条件不满足,要做的事情(if 语句的对立面)。
  • else 语句的语法:
if (判断条件) {条件满足时,要做的事情} else {条件不满足,要做的事情}
解释:
  • 否则,如果 判断条件 为假,就执行 条件不满足时要做的事情。

二、 三元运算符

三元运算符的作用与 if...else 语句类似。
作用:根据判断条件的真假,得到不同的结果
语法:
结果 = 判断条件 ? 值1 : 值2
解释:
  • 如果判断条件为真,结果为 值1;
  • 否则,如果判断条件为假,结果为 值2。
注意:得到结果的类型由值1和值2的类型决定(值1和值2的类型相同)。

三、 循环语句

3.1 概述

生活中,经常重复做某件事情,比如:
1. 上学时作业写 3 遍。
2. 女朋友说:爱我就对我说 100 遍“我爱你”。
需求:在 TS 中,打印 3 遍以下内容:
'北冥有鱼,其名为鲲。鲲之大,一锅装不下'
在 TypeScript 中,要实现重复做某件事情,就需要用到循环语句,来减少重复劳动提升效率。

3.2 for 循环

在 TypeScript 中,for 循环就是实现重复做某件事情的循环语句。
注意:for 循环是 TS 基础知识的重难点,语法比较复杂。
上学时作业写 3 遍。先准备,写作业的遍数,默认为:1。
  • 第 1 遍:先判断遍数是否 <= 3(是);写作业;遍数 + 1(准备开始第2遍)。
  • 第 2 遍:先判断遍数是否 <= 3(是);写作业;遍数 + 1(准备开始第3遍)。
  • 第 3 遍:先判断遍数是否 <= 3(是);写作业;遍数 + 1(准备开始第4遍)。
  • 第 4 遍:先判断遍数是否 <= 3(否);结束写作业。
for 循环的组成:
1. 初始化语句:声明计数器变量用来记录循环次数(执行一次)。
2. 判断条件:判断循环次数是否达到目标次数。
3. 计数器更新:完成一次循环让计数器数量加1。
4. 循环体:循环的代码,也就是要重复做的事情。

3.3 for 循环的基本使用

  • 语法:
for (初始化语句; 判断条件; 计数器更新) { 循环体
}
解释:
  • 初始化语句:声明计数器变量,记录循环次数。
  • 判断条件:判断循环次数是否达到目标次数。
  • 计数器更新:计数器数量加1。
  • 循环体:重复执行的代码,也就是要重复做的事情。
// 作业写 3 遍:
for (let i: number = 1; i <= 3; i++) {
console.log('北冥有鱼,其名为鲲。鲲之大,一锅装不下')
}

3.4 for 循环的执行过程

意义:for 循环的语法比较复杂,搞明白代码执行顺序,才是真正理解并掌握了 for 循环。
1. 初始化语句:只会执行一次。
2. 重复执行的部分:判断条件、循环的代码、计数器更新(绿色框框)。
  • 说明:红色表示当前执行的代码。
for (let i: number = 1; i <= 3; i++) {
console.log('...一锅装不下')
}
执行过程记录:
// 初始化计数器(i = 1) -- 只执行一次// 第 1 次: a 判断条件(1 <= 3)b 循环的代码->打印 c 计数器++(i变为2);
// 第 2 次: a 判断条件(2 <= 3)b 循环的代码->打印 c 计数器++(i变为3);
// 第 3 次: a 判断条件(3 <= 3)b 循环的代码->打印 c 计数器++(i变为4);
// 第 4 次: a 判断条件(4 <= 3),条件不满足,结束循环。

3.5 断点调试

疑问:老师是如何知道 for 循环执行过程的呢?断点调试
借助断点调试,观察代码的执行过程。
断点(Breakpoint):程序暂停的位置(调试时,程序运行到此处,就会暂停)。

3.6 break和continue

breakcontinue 常用在循环语句中,用来改变循环的执行过程。
for 循环执行的特点是:连续且不间断。
例子:买了 5 个包子,吃包子。
for (let i: number = 1; i <= 5; i++) { console.log('正在吃第' + i + '个包子')
}
break 能够让循环提前结束(终止循环)。
例子:买了 5 个包子,吃包子。
场景:吃到(没吃)第3个饱了,剩下的就不吃了。
for (let i: number = 1; i <= 5; i++) { if (i === 3) { break }console.log('正在吃第' + i + '个包子')
}
continue 能够让循环间断执行(跳过本次循环,继续下一次循环)。
例子:买了 5 个包子,吃包子。
场景:吃到第3个有虫子,这个就不再吃了,但没吃饱,继续吃下一个。
for (let i: number = 1; i <= 5; i++) { if (i === 3) { continue }console.log('正在吃第' + i + '个包子')
}

四、 断点调试

TypeScript 数组

一、 数组概述

问题1:存储一个人的名字,怎么存? 声明一个字符串类型的变量
let name1: string = '迪丽热巴'

问题2:存储三个人的名字,怎么存? 声明三个字符串类型的变量
let name1: string = '迪丽热巴'
let name2: string = '古力娜扎'
let name3: string = '马尔扎哈'

问题3:如何是存储一个班级中所有人的名字呢?
存储多个数据时,声明多个变量就太繁琐了。
数组,是用于存放多个数据的集合。
有数组:只需要使用一个数组([]),就可以存储任意多个数据。
let names: string[] = ['迪丽热巴', '古力娜扎', '马尔扎哈']

没有数组:存储三个人的名字,就需要三个字符串类型的变量。
let name1: string = '迪丽热巴'
let name2: string = '古力娜扎'
let name3: string = '马尔扎哈'

注意:数组中,通常是相同类型的数据。

二、 创建数组---2种方式

创建数组有两种语法形式。
  • 语法一(推荐):
let names: string[] = []

[](中括号)表示数组。如果数组中没有内容,就是一个空数组。
数组的类型注解由两部分组成:类型+[]。此处表示字符串类型的数组(只能出现字符串类型)。
let names: string[] = ['迪丽热巴', '古力娜扎', '马尔扎哈']
数组,多个元素之间使用逗号(,)分隔。
数组中的每一项内容称为:元素。

  • 语法二(不推荐):
let names: string[] = new Array()

功能与 [] 相同,但是更加繁琐:
let names: string[] = []

数组中有数据时:
let names: string[] = new Array('迪丽热巴', '古力娜扎', '马尔扎哈')
// 相当于:
let names: string[] = ['迪丽热巴', '古力娜扎', '马尔扎哈']

三、 数组长度和索引

3.1 概述

生活中,我们经常会排队(比如:排队吃饭)。
队伍的特征:1 长度 2 顺序和序号(队伍中的每个人)。
我们可以把数组想象成这个队伍,因为数组也有长度,也有顺序并且数组中的每个元素也有序号。

3.2 数组长度

数组长度:表示数组中元素的个数,通过数组的 length 属性来获取。
let foods: string[] = ['煎饼', '馒头', '米饭']

获取数组长度:
console.log(foods.length) // 3

3.2 数组索引

数组中的每个元素都有自己的序号。

我们把数组中元素的序号,称为:索引(下标),数组中的元素与索引一一对应。
注意:数组索引是从 0 开始的。

let foods: string[] = ['煎饼', '馒头', '米饭']
// 数组的索引分别为: 0 1 2

问题:该数组的长度(length)和最大索引之间有什么关系? 最大索引为:length - 1
数组是有序的集合,用来存储多个数据。

总结:

问题1:如何获取数组长度?  foods.length
问题2:数组索引是从几开始的? 索引从 0 开始

四、 取值和存值

4.1 取值

从数组中,获取到某一个元素的值,就是从数组中取值。(比如,获取最爱的食物 – 煎饼)

let foods: string[] = ['煎饼', '馒头', '米饭']
// 数组的索引分别为: 0 1 2

数组中的元素与索引是一一对应的,通过索引获取到某一个元素的值。
语法:
数组名称[索引]

比如,获取到最爱的食物 – 煎饼:

console.log(foods[0]) // 煎饼

4.2 存值

如果要修改数组中某个元素的值,就要使用数组存值。(比如,不爱吃馒头,将馒头替换为包子)

let foods: string[] = ['煎饼', '馒头', '米饭']// 数组的索引分别为: 0 1 2

技巧:先获取到要修改的元素,然后,再存值。
语法:
数组名称[索引] = 新值

比如,将馒头替换为包子:

foods[1] = '包子'
console.log(foods) // ['煎饼', '包子', '米饭']

4.3 添加元素

存值的语法是:数组名称[索引] = 新值,根据索引是否存在,有两种功能:1 修改元素 2 添加元素。

let foods: string[] = ['煎饼', '馒头', '米饭']// 数组的索引分别为: 0 1 2
1. 如果索引存在,就表示:修改元素。
foods[1] = '包子'

2. 如果索引不存在,就表示:添加元素。
foods[3] = '油泼面'
console.log(foods) // ['煎饼', '馒头', '米饭', '油泼面']

添加元素的通用写法:数组名称[数组长度] = 新值

五、遍历数组

遍历数组,也就是把数组中的所有元素挨个获取一次(比如,计算数组中所有数字的和)。

let nums: number[] = [100, 200, 300]// 数组的索引分别为: 0 1 2

通过数组取值的方式,就可以一个个取出来:
console.log(nums[0]) // 100
console.log(nums[1]) // 200
console.log(nums[2]) // 300

存在问题:太繁琐,相似的代码重复多次。
重复做某件事情,可以使用 for 循环。
重复取值的规律:索引号自增(每次加1 ),而 for 循环的计数器i也是自增的。

遍历数组,也就是把数组中的所有元素挨个获取一次(比如,计算数组中所有数字的和)。

let nums: number[] = [100, 200, 300]// 数组的索引分别为: 0 1 2
推荐,使用for循环遍历数组:
for (let i: number = 0; i <= nums.length - 1; i++) {
console.log(nums[i])}
简化判断条件(计数器i的值为整数,所以,i<=2 与 i<3 作用相同):
for (let i: number = 0; i < nums.length; i++) {
console.log(nums[i])}

注意1:因为数组索引是从0开始的,所以计数器i的默认值为0
注意2:应该根据数组长度来计算,公式为数组长度减一,也就是:nums.length – 1(最大索引)。
优势:不管数组中元素的数量怎么变化,for循环的判断条件不需要改动。

总结:

遍历数组,也就是把数组中的所有元素挨个获取一次。
问题1:如果要遍历数组应该使用什么语句?  for循环语句
问题2:for循环计数器的默认值是多少?  默认值为:0
问题3:for循环的判断条件是什么? i < nums.length

TypeScript 函数基础

一、 函数概述

需求:计算数组nums中所有元素的和。
let nums: number[] = [1, 3, 5]

let sum: number = 0
for (let i: number = 0; i < nums.length; i++) {
sum += nums[i]
}
console.log(sum)

问题:如果还要计算其他数组(nums2)中所有元素的和呢? 拷贝一份代码,修改
let nums2: number[] = [2, 4, 6]

存在的问题:相似的代码重复写,代码冗余。

正确的姿势:使用函数来包装(封装)相似的代码,在需要的时候调用函数,相似的代码不再重复写。
function getSum(nums: number[]) {
let sum: number = 0
for (let i: number = 0; i < nums.length; i++) {
sum += nums[i]
}
console.log(sum)
}
getSum(nums1) // 计算nums1中所有元素的和
getSum(nums2) // 计算nums2中所有元素的和

所谓函数,就是声明一次但却可以调用任意多次的一段代码。
意义:实现代码复用,提升开发效率。
封装:将一段代码包装起来,隐藏细节。

二、函数的使用

函数的使用分为两步:1 声明函数 2 调用函数 (类比变量)。
  • 第一步:声明函数
function 函数名称() {
函数体
}

解释:
  • 函数名称:推荐以动词开头,因为函数表示做一件事情,实现一个功能。
  • 函数体:表示要实现功能的代码,复用的代码。
function sing() {
console.log('五环之歌')}
  • 第二步:调用函数
函数名称()

比如,调用 sing 函数:

sing()

注意:只有调用函数后,函数中的代码才会执行。

总结:
1. 函数的基本使用分为哪两步? 1 声明函数 2 调用函数
2. 声明函数的关键字是什么? function
3. 不调用函数,函数中的代码会执行吗? 不会
// 1 声明函数
function sing() {
console.log('五环之歌')
}
// 2 调用函数
sing()

三、函数参数

3.1 概述

需求:让唱歌的函数(sing),每次调用时,“唱”不同的歌。
function sing() {
console.log('五环之歌')
}
sing() // 五环之歌
sing() // 五环之歌

原因:函数(sing)中歌曲名称是固定值。
存在的问题:函数(sing)只能“唱”固定的歌,太死板,没有体现出函数复用的灵活性。

使用函数参数来实现:

// 调用函数时,告诉函数要唱的歌曲名称
sing('五环之歌')
sing('探清水河')
// 声明函数时,接收传入的歌曲名称
function sing(songName: string) {
console.log(songName)
}

函数(sing)中歌曲名称:固定值 --> 动态传入的值。
函数参数的作用:增加了函数的灵活性、通用性,针对相同的功能,能够适应更多的数据(值)。

3.2 形参和实参

函数参数分为两部分:1 形参 2 实参。
1. 形参:声明函数时指定的参数,放在声明函数的小括号中(挖坑)。
function sing(songName: string) { }

  • 语法:形参名称: 类型注解,类似于变量声明,但是没有赋值。
  • 作用:指定函数可接收的数据。
然后,就可以在函数体中,像使用变量一样使用形参了。
2. 实参:调用函数时传入的参数,放在调用函数的小括号中(填坑)。
sing('五环之歌')

  • 实参是一个具体的值(比如:‘字符串’、18、[]等),用来赋值给形参。
形参和实参的总结:
  • 声明函数时的参数,叫什么?作用? 形参,指定函数能够接收什么数据。
  • 调用函数时的参数,叫什么?作用? 实参,是一个具体的值,用来赋值给形参。
function sing(songName: string) { }
sing('五环之歌')

通过形参和实参的配合,函数可以接收动态数据,从而让函数变得更加灵活、强大。

3.3 其他说明

1. 根据具体的功能,函数参数可以有多个,参数之间使用逗号(,)来分隔。

function fn(name: string, age: number) { }
fn('刘老师', 18)

2. 实参和形参按照顺序,一一对应。
function fn(name: string, age: number) { }fn('刘老师', 18) // name -> '刘老师', age -> 18

3. 实参必须符合形参的类型要求,否则会报错!

function sing(songName: string) {}
sing(18) // 报错! 形参要求是 string 类型,但是,实参是 number 类型。

技巧:调用函数时,鼠标放在函数名称上,会显示该函数的参数以及类型。

总结:
  • 函数形参是 string 类型,调用该函数时传入 18 对吗?  不对,因为实参不符合形参的类型要求
  • 函数有多个参数时,多个参数之间用什么符号分隔? 逗号
  • 以下代码会报错吗? 报错!因为函数sing要求有一个参数,但是没有传
function sing(songName: string) { }
sing() // 报错!

四、 函数返回值

4.1 概述

函数返回值的作用:将函数内部计算的结果返回,以便于使用该结果继续参与其他的计算。
需求:计算以下两次调用结果的和。

getSum([1, 3, 5]) // 9
getSum([10, 100, 1000]) // 1110

getSum([1, 3, 5]) + getSum([10, 100, 1000]) // 9 + 1110 => 1119

关键点:拿到函数(getSum)内部计算出来的结果,然后,才能进行后续的加法计算。
注意:如果没有指定函数的返回值,那么,函数返回值的默认类型为 void(空,什么都没有)。

4.2 基本使用

步骤:1 指定返回值类型 2 指定返回值
1. 指定返回值类型
function fn(): 类型注解 {
}

  • 在声明函数的小括号后面,通过 : 类型注解 指定。
function fn(): number {
}
2. 指定返回值
function fn(): 类型注解 {
return 返回值
}
  • 在函数体中,使用 return 关键字来返回函数执行的结果。
function fn(): number {
return 18
}

  • 注意:返回值必须符合返回值类型的类型要求,否则会报错!
1. 使用变量接收函数返回值
let result: 类型注解 = fn()

使用变量接收函数返回值的时候,相当于:直接将返回值赋值给变量。
let result: number = 18

注意:变量(result)的类型与函数(fn)的返回值类型要一致。
然后,就可以使用这个变量(返回值),继续进行其他计算了。
2. 直接使用函数调用的结果(返回值),进行其他计算
console.log( fn() * 10 )
总结:
  • 使用哪个关键字来指定返回值? return
  • 以下代码是否正确?  错误!因为返回值18不符合返回值类型string的要求
function foo(): string {
return 18
}

  • 如果函数(getSum)返回了数组中所有元素的和,以下代码表示什么?
getSum([1, 3, 5]) + getSum([10, 100, 1000])

4.3 return 的说明

1. 将函数内部的计算结果返回。
2. 终止函数代码执行,即:return 后面的代码不会执行。
function fn(): number {
return 18
console.log('我不会执行,放在这,没有意义')
}

3. return 只能在函数中使用,否则会报错。

4. return 可以单独使用(后面可以不跟内容),用来刻意终止函数的执行。
function play(age: number): void {
if (age < 18) {
return
}
console.log('网吧上网好爽啊,王者、吃鸡两不误')
}
play(16) // 情况1:进入if后return,后续代码不执行
play(20) // 情况2:不进if,直接打印内容: 网吧上网好爽啊,王者、吃鸡两不误

注意:如果函数没有返回值,默认返回值类型是:void(空),可省略不写。
function play(age: number) { /* ... */ }

return 的总结:

  • 能否在函数外面使用 return? 不能
  • return 后面不跟内容,单独使用,表示什么?  不会执行
  • return 后面的代码会执行吗? 刻意终止函数代码执行
  • 函数没有返回值,默认返回值类型是什么? void

函数基础总结

函数,即:声明一次但却可以调用任意多次的一段代码。
通过将要实现的功能,使用函数封装起来,实现代码复用,提升开发效率。
函数的三种主要内容: 1 参数 2 函数体 3 返回值。
简化过程:
         1. 输入(参数) -- 可选
        2. 处理(函数体)
         3. 输出(返回值)-- 可选

TypeScript 函数进阶

一、函数调试

1.1 基本操作

借助断点调试,观察代码的执行过程。
关键点:1 在哪个位置打断点? 2 如何调试?
一.断点位置:函数调用所在位置。
二.调试函数常用按钮:
单步调试:表示执行下一行代码,但是,遇到函数调用时,进入函数内部。
单步跳出:表示跳出当前函数(函数中的代码执行完成),继续执行函数调用后的下一行代码。

1.2 函数的执行过程

示例:
function work() {
console.log('早上9点开始工作')
play()
console.log('晚上6点结束工作')
}
function play() {
console.log('早上9:30开始吃鸡')
console.log('晚上5:30结束吃鸡')
}
work()

结论1:函数里面,还可以继续调用其他函数。
结论2:函数,按照顺序一行行的执行代码,当遇到调用其他函数时,先完成该函数调用,再继续执行代码。

二、 变量作用域

一个变量的作用域指的是:代码中定义变量的区域,它决定了变量的使用范围。
在 TS(或JS)中,函数可以形成作用域,叫做:函数作用域。
根据范围的不同,变量可以分为两种:1 局部变量 2 全局变量。
  • 局部变量:表示在函数内部声明的变量,该变量只能在函数内部使用(局部地区有雨)。
  • 全局变量:表示在函数外部声明的变量,该变量在当前 ts 文件的任何地方都可以使用。
function fn() {
// 变量 num 是局部变量
let num: number = 1
console.log(num) // 此处能访问到变量 num
}
fn()
console.log(num) // 问题:此处能访问到变量 num 吗? 不能
// 变量 num 是全局变量
let num: number = 1
function fn() {
console.log(num) // 问题:此处能访问到变量 num 吗?  能
}
fn()
console.log(num) // 问题:此处能访问到变量 num 吗? 能

TypeScript 对象

一、对象概述

生活中,对象是一个具体的事物,比如:你的电脑、你的手机、古力娜扎、周杰伦(周董)等都是对象。
程序员都知道:万物皆对象。
这些具体的事物,都有自己的特征和行为:
特征:
你的电脑:尺寸、重量、价格等
你的手机:品牌、屏幕大小、颜色等
古力娜扎:年龄、身高、三围等

行为:
你的电脑:浏览网页、写代码等
你的手机:播放视频、吃鸡等
古力娜扎:演电影、配音等
TypeScript 中的对象,是对生活中具体事物的抽象,使得我们可以通过代码来描述具体的事物。
TS 中的对象,也是由特征和行为组成的,它们有各自专业的名称:属性(特征)和方法(行为)。
  • 理解 TS 中的对象:一组相关属性和方法的集合,并且是无序的。
// 演示对象:
{
name: '周杰伦',
gender: '男',
height: 175,
sing: funtion () {
console.log('故事的小黄花 从出生那年就飘着')
}
}
疑问:为什么要有对象?
需求:使用 TS 代码描述周杰伦。
方案一:使用多个变量
let name: string = '周杰伦'
let gender: string = '男'
let height: number = 175
function sing() { ... }

缺点:一个变量只能存储一个数据,多个变量之间没有任何关联(相关性)。
疑问:为什么要有对象?
需求:使用 TS 代码描述周杰伦。
方案二:使用数组,一次可以存储多个数据:
['周杰伦', '男', 175, function sing() { ... }]

缺点:不知道数组中的每个元素表示什么。
正确姿势:使用对象,对象在描述事物(一组相关数据)时,结构更加清晰、明了。
{ name: '周杰伦', gender: '男', height: 175, sing: function () { ... }}
总结:
对象:一组相关属性和方法的集合,并且是无序的。
在 TS 中,如果要描述一个事物或一组相关数据,就可以使用对象来实现。

二、 创建对象

注意:先学习对象的基本使用,再学习对象的类型注解(对象的类型注解类似于对象自身的语法)。
对象的语法:
let person = {}

此处的 {}(花括号、大括号)表示对象。而对象中没有属性或方法时,称为:空对象。
对象中的属性或方法,采用键值对的形式,键、值之间使用冒号(:)来配对。
键(key)-->名称 ,值(value)--> 具体的数据。
多个键值对之间,通过逗号(,)来分隔(类比数组)。
现在,对象person具有两个属性:
let person = { name: '刘老师', age: 18 }

属性和方法的区别:值是不是函数,如果是,就称为方法;否则,就是普通属性。
let person = {
sayHi: function () {
console.log('大家好,我是一个方法')}
}

注意:函数用作方法时可以省略function后面的函数名称,也叫做匿名函数。
函数没有名称,如何调用? 此处的sayHi相当于函数名称,将来通过对象的sayHi就可以调用了。
如果一个函数是单独出现的,没有与对象关联,我们称为函数;否则,称为方法。
总结:
对象中的属性或方法,采用键值对的形式,因此,对象是无序键值对的集合。
  • 使用什么符号创建对象?     花括号({})
  • 键(key)、值(value)之间通过什么符号配对? 冒号(:)
  • 多个属性或方法之间使用什么符号分隔?  逗号(,)
  • 属性和方法的区别? 值是不是函数

三、接口

3.1 对象的类型注解

TS 中的对象是结构化的,结构简单来说就是对象有什么属性或方法。
在使用对象前,就可以根据需求,提前设计好对象的结构。
比如,创建一个对象,包含姓名、年龄两个属性。
思考过程:1 对象的结构包含姓名、年龄两个属性 2 姓名 -->字符串类型,年龄--> 数值类型 3 创建对象。
这就是对象的结构化类型(左侧),即:对该对象值(右侧)的结构进行类型约束。
或者说:建立一种契约,约束对象的结构。
语法说明:
对象类型注解的语法类似于对象自身的语法。
注意:键值对中的值是类型!(因为这是对象的类型注解)。
注意:多个键值对之间使用分号(;)分隔,并且分号可省略。

总结:
TS 中的对象是结构化的,在使用对象前,就可以根据需求,提前设计好对象的结构。
对象的结构化类型(类型注解):建立一种契约,约束对象的结构。
注意点:类型注解中键值对的值为类型!

3.2 对象方法的类型注解

问题:如何给对象中的方法,添加类型注解?
技巧:鼠标放在变量名称上,VSCode就会给出该变量的类型注解。
let person: {
sayHi: () => void
sing: (name: string) => void
sum: (num1: number, num2: number) => number
}

箭头(=>)左边小括号中的内容:表示方法的参数类型。
箭头(=>)右边的内容:表示方法的返回值类型。
方法类型注解的关键点:1 参数 2 返回值。
注意:技巧是辅助,更重要的是理解。

3.3 接口的使用

直接在对象名称后面写类型注解的坏处:1 代码结构不简洁 2 无法复用类型注解。
接口:为对象的类型注解命名,并为你的代码建立契约来约束对象的结构。
语法:
interface 表示接口,接口名称约定以I开头。
推荐:使用接口来作为对象的类型注解。

四、 取值和存值

4.1 取值

取值,即:拿到对象中的属性或方法并使用。
获取对象中的属性,称为:访问属性。
获取对象中的方法并调用,称为:调用方法。
  • 访问属性
let jay = { name: '周杰伦', height: 175 }

需求:获取到对象(jay)的name属性。
console.log(jay.name)

说明:通过点语法(.)就可以访问对象中的属性。
技巧:在输入点语法时,利用VSCode给出来的提示,利用上下键快速选择要访问的属性名称。
  • 调用方法
let jay = {
sing: function () {
console.log('故事的小黄花 从出生那年就飘着')
}
}

需求:调用对象(jay)的sing方法,让他唱歌。
jay.sing()

说明:通过点语法(.)就先拿到方法名称,然后,通过小括号调用方法。
补充说明:
console.log(参数1, 参数2, ...)

实际上,console是一个对象,而log是该对象提供的一个方法。
并且,log方法可以有多个参数。
console.log('我叫', jay.name)

总结:

通过什么符号,来访问对象中的属性或方法?
点语法(.)
技巧:通过点语法,访问对象属性时,利用VSCode出来的提示,快速选择要访问的属性或方法。
该技巧很实用,特别是访问别人创建的对象时(比如:console对象)。
注意:方法需要调用,所以,通过点语法拿到方法名称后,不要忘记使用小括号调用!

4.2 存值

存值,即修改(设置)对象中属性的值。
let jay = { name: '周杰伦', height: 175 }

需求:将对象(jay)的name属性的值修改为'周董'。
jay.name = '周董'

解释:先通过点语法获取到name属性,然后,将新值'周董'赋值给该属性。
console.log(jay.name) // 周董

注意:设置的新值,也必须符合该属性的类型要求!
注意:几乎不会修改对象中的方法。

总结:

对象是对现实生活中具体事物(特征和行为)的抽象,可以使用对象来描述这些具体的事物。
对象包含:1 属性 2 方法。
简单来说:对象就是无序键值对的集合。
对象是结构化的,它的类型注解就是从对象的结构(属性、方法)出发,进行类型约束和检查。
推荐:使用接口来作为对象的类型注解,建立一种契约,约束对象的结构。
TS中的数据类型分为两大类:1 原始类型(基本数据类型) 2 对象类型(复杂数据类型)。
常用的基本数据类型有 5 个:number / string / boolean / undefined / null。
复杂数据类型:object(对象、数组)、function(函数)。

五、内置对象

5.1 概述

对象的两种来源:1 自己创建 2 其他人创建(编程语言自带或第三方)。
内置对象,是 TS/JS 自带的一些基础对象,提供了TS开发时所需的基础或必要的能力。
已经用过的内置对象:数组。
1. 学习内置对象,需要学什么? 常用属性和方法
2. 怎么学?  查文档

5.2 学习方式 - 查文档

注意:内置对象中提供了非常多的方法或属性,以满足开发中各种各样的需求。
编程不是死记硬背,而是掌握一定的技巧,查文档就是最重要的一个。
文档地址:MDN(更标准) / W3school(国内)

总结:

内置对象,是 TS/JS 自带的一些基础对象,提供了TS开发时所需的基础或必要的能力。
学什么?学内置对象中的属性或方法。
怎么学?查文档,文档地址:MDN(更标准) / W3school(国内)

Web 开发

一、Web 开发基础

1.1 概述

下棋游戏(XXOO)是通过 Web(网页)开发实现的,因此,我们要学习 Web 开发的相关知识。
Web 开发涵盖以下内容:HTML、CSS、JavaScript 
三者之间的关系:
  • (结构)HTML 负责创建页面结构。
  • (样式)CSS 负责美化页面结构(相当于化妆)。
  • (行为)JavaScript 负责让页面“动”起来,解锁更多动效。

1.2 HTML

HTML(Hyper Text Markup Language,即:超文本标记语言)负责创建页面结构。
创建第一个 HTML 步骤:
2. 快速生成 HTML 基本骨架:在文件中输入英文叹号(!),然后,按 tab 键。
1. 创建 a.html 文件。
3. 创建按钮标签:在 body 标签中,输入 button,按 tab 键。
4. 打开 HTML 页面:在文件夹中找到页面文件,双击打开。
注意:页面中可见的内容,写在 body 标签中。

1.3 CSS

CSS(Cascading Style Sheets,即:层叠样式表)负责美化页面结构。
使用 CSS 的三种方式:
1. style 属性:在 HTML 标签中,通过 style 属性来添加样式。
<p style="color: red; font-size: 50px;">天青色等烟雨 ...</p>

2. style 标签:在 head 标签中,创建 style 标签。
<style>
/* 标签选择器 */
p { color: red; }
</style>

技巧: 先通过选择器获取标签,再设置样式。
常用的 CSS 选择器:
/* 标签选择器 */
p { color: red; }
/* id 选择器 */
#txt { font-size: 50px; }
/* 类(名)选择器 –- 推荐 */
.cls { backgroud-color: pink; }

推荐:使用 类选择器 来给标签添加样式!
3. CSS 文件:创建 .css 文件,将样式放在该文件中,然后在 head 中通过 link 标签引入该文件。
<link ref="stylesheet" href="./index.css" />

总结:

作用:美化页面结构。
使用方式:
1. HTML 标签的 style 属性。
2. style 标签(在 head 标签中创建)。
3. CSS 文件(在 head 中通过 link 标签引入)。
常用的 CSS 选择器:
p { color: red; } /* 标签选择器 */
#txt { font-size: 50px; } /* id 选择器 */
.cls { backgroud-color: pink; } /* 类(名)选择器 –- 推荐 */

1.4 浏览器中使用 JavaScript

JavaScript(简称:JS),负责让页面“动”起来,为页面添加动效。
使用 JS 的两种方式:
1. script 标签:在 body 标签的最后面,创建 script 标签。
注意:console.log 方法打印的内容,需要在浏览器控制台中查看。
打开控制台(console)的方式:在页面中点击鼠标右键,选择“检查”,切换到 Console 面板。
2. 独立 js文件:创建 index.js 文件,在 body 标签的最后面,通过 script 标签引入。
<script src="./index.js"></script>

1.5 自动刷新浏览器

问题:每次修改页面内容后,都要手动刷新浏览器,才能看到修改后的内容。
解决方式:使用 VSCode 的 Live Server 插件,实现自动刷新浏览器。
如何使用?
作用:监视 html 或引入的css、js的变化,在保存文件时,该插件就会帮我们自动刷新浏览器。
注意:不再双击打开 html 页面!
使用方式:在 html 文件中,点击鼠标右键,再点击 Open with Live Server 按钮即可。
注意:html 文件所在的文件夹名称不要包含中文,否则,打开页面失败,插件功能无法生效!

二、浏览器中运行TS

注意:浏览器中只能运行 JS,无法直接运行 TS,因此,需要将 TS 转化为 JS 然后再运行。
浏览器中运行 TS 的步骤:
1. 使用命令 tsc index.ts 将 ts 文件转化为 js 文件。
2. 在页面中,使用 script 标签引入生成的 js 文件(注意是 js 文件)。
<script src="./index.js"></script>

问题:每次修改 ts 文件后,都要重新运行 tsc 命令将 ts 转化为 js 。
解决方式:使用 tsc 命令的监视模式。
tsc --watch index.ts

解释: --watch 表示启用监视模式,只要重新保存了 ts 文件,就会自动调用 tsc 将 ts 转化为 js。

三、 DOM 操作--2步走

3.1 概述

DOM(Document Object Modal):文档对象模型。
DOM 是浏览器提供的(浏览器特有),专门用来操作网页内容的一些 JS 对象。
目的:让我们可以使用 JS/TS 代码来操作页面(HTML)内容,让页面“动”起来,从而实现 Web 开发。
HTML:超文本标记语言,用来创建网页结构。
两者的关系:浏览器根据 HTML 内容创建相应的 DOM 对象,也就是:每个 HTML 标签都有对应的 DOM 对象 。
学习四个常用 DOM 操作:1 获取 DOM 元素(DOM 对象) 2 设置样式 3 设置内容 4 绑定(解绑)事件。
DOM 操作的套路(技巧):先找人 后做事。
  • 找人:获取 DOM 元素。
  • 做事:设置样式、内容、绑定(解绑)事件。
document.title = '等你下课'

比如: 将 p 标签中的内容修改为:天青色等烟雨而我在等你。
步骤: 1 获取 p 元素 2 设置内容。

总结:

DOM 是浏览器提供的(浏览器特有),专门用来操作网页内容的一些 JS 对象(API)。
通过 DOM 操作,可以让 JS/TS 控制页面(HTML)内容,让页面“动”起来,从而实现 Web 开发。
HTML 标签和 DOM 的关系:每个 HTML 标签都有对应的 DOM 对象。
DOM 操作的套路(技巧):先找人 后做事。

3.2 获取元素

常用方法有两个:
  • querySelector(selector) 作用:获取某一个 DOM 元素。
  • querySelectorAll(selector) 作用:同时获取多个 DOM 元素。
1. 获取一个 DOM 元素:
document.querySelector(selector)

document 对象:文档对象(整个页面),是操作页面内容的入口对象。
selector 参数:是一个 CSS 选择器(标签、类、id 选择器等)。
作用:查询(获取)与选择器参数匹配的 DOM 元素,但是,只能获取到第一个!

推荐:使用 id 选择器(唯一)。
let title = document.querySelector('#title')

解释:获取页面中 id 为 title 的 DOM 元素。

类型断言

问题:调用 querySelector() 通过 id 选择器获取 DOM 元素时,拿到的元素类型都是 Element。
因为无法根据 id 来确定元素的类型,所以,该方法就返回了一个宽泛的类型:元素(Element)类型。
不管是 h1 还是 img 都是元素。
导致新问题:无法访问 img 元素的 src 属性了。
因为:Element 类型只包含所有元素共有的属性和方法(比如:id 属性)。
解决方式:使用类型断言,来手动指定更加具体的类型(比如,此处应该比 Element 类型更加具体)。
语法:
值 as 更具体的类型

比如:
let img = document.querySelector('#image') as HTMLImageElement

解释:我们确定 id="image" 的元素是图片元素,所以,我们将类型指定为 HTMLImageElement。
技巧:通过 console.dir() 打印 DOM 元素,在属性的最后面,即可看到该元素的类型。
 

总结:
类型断言:手动指定更加具体(精确)的类型。
使用场景:当你比 TS 更了解某个值的类型,并且需要指定更具体的类型时。
// document.querySelector() 方法的返回值类型为: Element
// 如果是 h1 标签:
let title = document.querySelector('#title') as HTMLHeadingElement
// 如果是 img 标签:
let image = document.querySelector('#image') as HTMLImageElement

技巧:通过 console.dir() 打印 DOM 对象,来查看该元素的类型。
2. 获取多个 DOM 元素:
document.querySelectorAll(selector)

作用:获取所有与选择器参数匹配的 DOM 元素,返回值是一个列表。
推荐:使用 class 选择器。
示例:
let list = document.querySelectorAll('.a')

解释:获取页面中所有 class 属性包含 a 的元素。

3.3 操作文本内容

读取:
dom.innerText

设置:
dom.innerText = '等你下课'

注意:需要通过类型断言来指定 DOM 元素的具体类型,才可以使用 innerText 属性。
注意:设置内容时,会覆盖原来的内容。如何实现追加内容(比如,青花瓷 --> 青花瓷-->周杰伦)?
dom.innerText = dom.innerText + ' – 周杰伦'
// 简化
dome.innerText += ' – 周杰伦'

3.4 操作样式

两种方式:
  • dom.style 属性:行内样式操作,可以设置每一个样式属性(比如,字体大小、文字颜色等)。
  • dom.classList 属性:类样式操作,也就是操作类名,比如,添加类名、移除类名等。
1. style 属性(行内样式)
读取:
dom.style.样式名称

设置:
dom.style.样式名称 = 样式值

说明:所有的样式名称都与 CSS 相通,但命名规则为驼峰命名法。

dom.style.fontSize = '30px'
dom.style.display = 'none'
2. classList 属性(类样式)
包含三个常用方法:添加、移除、判断是否存在。
添加:
dom.classList.add(类名1, 类名2, ...)

参数表示:要添加的类名,可以同时添加多个。
比如:
<p class="a"></p>
dom.classList.add('b', 'c') // 添加 class 样式 ==> class="a b c"
移除:
dom.classList.remove(类名1, 类名2, ...)

参数表示:要移除的类名,可以同时移除多个。
比如:
<p class="a b c"></p>
dom.classList.remove('a', 'c') // 移除 class 样式 ==> class="b"
判断类名是否存在:
let has = dom.classList.contains(类名)

参数表示:要判断存在的类名。
比如:
<p class="b"></p>
dom.classList.contains('a') // false
dom.classList.contains('b') // true

总结:

类样式(classList)的操作有三种:
// 添加
dom.classList.add('a', 'b')
// 移除
dom.classList.remove('b', 'c')
// 判断是否存在
let has = dom.classList.contains('a')

3.5 操作事件

在浏览网页时,我们经常会通过移入鼠标、点击鼠标、敲击键盘等操作,来使用网站提供的功能。
如果要让我们自己实现这样的功能,就需要通过操作事件来实现了。
实际上,移入鼠标、点击鼠标、敲击键盘等,都是常见的 DOM 事件。
操作事件的两个方法:
  • addEventListener 添加(绑定)事件。
  • removeEventListener 移除(解绑)事件。

1. addEventListener 添加事件

作用:给 DOM 元素添加事件。
dom.addEventListener(事件名称, 事件处理程序)

事件名称:字符串,比如:'click'(鼠标点击事件)、'mouseenter'(鼠标进入事件)。
事件处理程序:回调函数,指定要实现的功能,该函数会在触发事件时调用。
示例:鼠标点击按钮,打印内容。
btn.addEventListener('click', function () {
console.log('鼠标点击事件触发了')
})
事件对象(event),是事件处理程序(回调函数)的参数。
表示:与当前事件相关的信息,比如:事件类型(type)、触发事件的 DOM 元素(target)等。
btn.addEventListener('click', function (event) {
console.log(event.type)
// click
console.log(event.target)
// btn 元素
})

2. removeEventListener 移除事件

作用:移除给 DOM 元素添加的事件,移除后,事件就不再触发了。
dom.removeEventListener(事件名称, 事件处理程序)

事件名称:同添加事件的第一个参数。
事件处理程序:必须要跟添加事件时的事件处理程序是同一个,否则无法移除!

2. removeEventListener 移除事件
正确方式:
function handleClick() {}
btn.addEventListener('click', handleClick)
btn.removeEventListener('click', handleClick)

说明:添加和移除事件时,事件处理程序是同一个,都是函数 handleClick。
错误演示:
btn.addEventListener('click', function () {})
btn.removeEventListener('click', function () {})

注意:以上两个函数虽然长的一样,却是不同的函数(双胞胎,不是同一个人)。
如果事件只需要触发一次,可以在添加事件时处理。
处理方式:传入第三个参数,将 once 属性设置为 true。
btn.addEventListener('click', function () {}, { once: true })

once :如果值为 true,会在触发事件后,自动将事件移除,达到只触发一次的目的。

移除事件总结:

当 DOM 元素的事件不再使用时,就可以通过 removeEventListener 方法移除事件。
注意:添加和移除的事件处理程序必须是同一个,否则无法移除!
function handleClick() {}
btn.addEventListener('click', handleClick)
btn.removeEventListener('click', handleClick)

如果事件只需要触发一次,可以在添加事件时,通过 once 属性来实现。
btn.addEventListener('click', function () {}, { once: true })

函数声明形式的事件处理程序说明

1. 可以先使用函数,再声明函数。
btn.addEventListener('click', handleClick)
function handleClick() {}

原因:函数声明在当前 ts 文件中的任意位置都有定义。
// 1 先调用函数
fn()
// 2 再声明函数
function fn() {}
2. 使用事件对象参数时,应该指定类型注解,否则,访问事件对象的属性时没有任何提示。
btn.addEventListener('click', handleClick)
function handleClick(event: MouseEvent) {
console.log(event.target)
}

技巧:使用原始方式(匿名回调函数)查看参数类型。

总结:

函数声明在当前 ts 文件中的任意位置都有定义。
btn.addEventListener('click', handleClick)
function handleClick() {}

fn() // 先调用函数
function fn() {} // 再声明函数
在函数声明形式的事件处理程序中,使用事件对象时,应该指定参数类型。
btn.addEventListener('click', handleClick)
function handleClick(event: MouseEvent) {}

typeScript(二)相关推荐

  1. Vue3+TypeScript从入门到进阶(六)——TypeScript知识点——附沿途学习案例及项目实战代码

    文章目录 一.简介 二.Vue2和Vue3区别 三.Vue知识点学习 四.TypeScript知识点 一.JavaScript和TypeScript 二.TypeScript的安装和使用 1.Type ...

  2. 【实习日记】第五天 剖析源码+学习Node.js Typescript基本语法

    国庆假期结束了,其实在这里实习对我而言还算是比较愉快的,虽然完成任务过程中出现的问题层出不穷,但也被克服问题的成就感包裹着,感觉每天在办公室就像在上自习一样.加油啦小荷! 自从把example运行成功 ...

  3. TS学习(二) :安装ts与ts配置

    一.安装TypeScript npm i -g typescript 二.安装完成后 创建ts 使用ts语法 可能遇到的报错问题 在啥都没配置的默认情况下,TS会做出下面几种假设: 假设当前的执行环境 ...

  4. Typescript和Javascript之间的区别

    目录 一.概要介绍 1.JavaScript 2.TypeScript 二.JavaScript 和 TypeScript 的主要差异 三.TypeScript 的优势 1. 静态输入 2. 大型的开 ...

  5. internal/modules/cjs/loader.js:883 throw err; ^Error: Cannot find module ‘typescript‘

    一.问题 internal/modules/cjs/loader.js:883 throw err; ^Error: Cannot find module 'typescript' 二.全局已经安装, ...

  6. ApacheCN NodeJS 译文集 20211204 更新

    Node API 开发入门指南 零.前言 一.Node.js 简介 二.构建 API--第 1 部分 三.构建 API--第 2 部分 React TypeScript Node 全栈开发 零.序言 ...

  7. 创建React + Ts项目

    一.安装react+ts npx create-react-app my-app --template typescript 二.安装eslint代码检测 yarn eslint npx eslint ...

  8. 【技能】前端技能列表

    一.基础 1. HTML 相关 2. CSS 相关 3. JavaScript 相关 类别 初级 高级 HTML HTML5 CSS CSS3 Less,Sass JS JavaScript ES6+ ...

  9. vue_2.0_fyf

    vue2.0 学习笔记 vue框架的两大核心: 一.前端开发历史 1994年可以看做前端历史的起点(但是没有前端的叫法) 1995年网景推出了JavaScript 1996年微软推出了iframe标签 ...

  10. Vue笔记随笔---kalrry

    Vue笔记随笔---kalrry VUE vue框架的两大核心: 一.前端开发历史 二.MV*模式 库 VS 框架 MVC架构模式 MVP架构模式 MVVM架构模式 vue是MVVM 三.开发工具 四 ...

最新文章

  1. [译]Javascript数列的push和pop方法
  2. 内核空间镜像攻击揭秘:ARM 硬件特性,竟能开启安卓8终端的上帝模式?
  3. Extjs 4.2 +Struts2 实现数据动态加载
  4. eeprom的wp 引脚_EEPROM存储芯片24C02
  5. 第一篇:容易遗忘的“枚举”
  6. python 文本处理 保留中英文和标点符号_问一下处理英文文本
  7. dos远程登录oracle,DOS批处理下 操作telnet实现自动远程登录操作
  8. oracle执行带有nbsp参数,Oracleamp;nbsp;参数文件amp;nbsp;spfileamp;nbsp;a
  9. iOS中__block 关键字的底层实现原理
  10. C# 中字符串string和字节数组byte[]的转换
  11. 洗头 Wet Hair
  12. 从达特茅斯会议到图灵奖---人工智能学习分享
  13. 当下的力量(解读版)
  14. CodeCademy | Python | 6. Pyglatin
  15. 在线引入 iconfont 特殊图标字体
  16. JS校验VIN码,生成虚拟VIN码
  17. Power BI可视化技巧:正负值配色
  18. java kryo register_kryo处理unmodifiedList报错问题
  19. [BLE]低功耗蓝牙介绍
  20. uefi装完系统后无法引导_uefi安装win10无法启动?uefi安装win10无法启动原因分析及解决方法...

热门文章

  1. java支付宝rsa2签名,使用支付宝SDK进行RSAj加签验签以及加密解密
  2. 基于神经网络的图像分割
  3. myeclispe 启动报错Location Type Faceted project metadata file /farming/.settings/org.eclips
  4. 【Android】自己动手做个扫雷游戏
  5. 爬取上交所公司信息,根据公司股票代码获取公司注册地址以及地址的经纬度
  6. c语言自动贩卖机设计报告,自动贩卖机课程设计.doc
  7. Springboot旅游管理系统 08841计算机毕业设计-课程设计-期末作业-毕设程序代做
  8. 劳务员培训建筑八大员培训劳务员对劳务分包企业管理的建议
  9. 使用ESP8266通过Blinker平台接入天猫精灵控制电视/空调
  10. 团队管理:新业务团队如何结合绩效来度量开发目标