1. 函数调试
1.1 函数的执行过程;
示例:
function work() {
console.log('早上9点开始工作')
play()
console.log('晚上6点结束工作')
}
function play() {
console.log('早上9:30开始吃鸡')
console.log('晚上5:30结束吃鸡')
}
work()
结论1:函数里面,还可以继续调用其他函数。
结论2:函数,按照顺序一行行的执行代码,当遇到调用其他函数时,先完成该函数调用,再继续执行代码。
所以:
- work()里面console.log(‘早上9点开始工作’)后
- 就执行调用函数play()
- 执行完了,回来再继续;
1.2 变量作用域
一个变量的作用域指的是:代码中定义变量的区域,它决定了变量的使用范围。
在 TS(或JS)中,函数可以形成作用域,叫做:函数作用域。
根据范围的不同,变量可以分为两种:1 局部变量 2 全局变量。
- 局部变量:表示在函数内部声明的变量,该变量只能在函数内部使用(局部地区有雨)。
function fn() {
// 变量 num 是局部变量
let num: number = 1
console.log(num) // 此处能访问到变量 num
}
fn()
console.log(num) // 问题:此处能访问到变量 num 吗? 不能
- 在函数里面申明的变量,就是局部变量
- 所以才有return,函数里面申明的变量,和计算的结果,是作用不到外面的
- 全局变量:表示在函数外部声明的变量,该变量在当前 ts 文件的任何地方都可以使用。
// 变量 num 是全局变量
let num: number = 1
function fn() {
console.log(num) // 问题:此处能访问到变量 num 吗?能
}
fn()
console.log(num) // 问题:此处能访问到变量 num 吗?能
2. TypeScript对象
目标:
- 能说出对象是什么
- 能创建对象
- 能使用TS接口
- 能获取对象中的属性
- 能使用数组的常用方法
2.1 对象概述
- 生活中,对象是一个具体的事物,比如:你的电脑、你的手机、古力娜扎、周杰伦(周董)等都是对象。
万物皆对象。
这些具体的事物,都有自己的特征和行为:
特征:
你的电脑:尺寸、重量、价格等
你的手机:品牌、屏幕大小、颜色等
古力娜扎:年龄、身高、三围等
行为:
你的电脑:浏览网页、写代码等
你的手机:播放视频、吃鸡等
古力娜扎:演电影、配音等
TypeScript 中的对象,是对生活中具体事物的抽象,使得我们可以通过代码来描述具体的事物。
TS 中的对象,也是由特征和行为组成的,它们有各自专业的名称:属性(特征)和方法(行为)。
理解 TS 中的对象:一组相关属性和方法的 集合,并且是 无序的。
对象更有点想是一坨数据
// 演示对象:
{
name: '周杰伦',
gender: '男',
height: 175,
sing: funtion () {
console.log('故事的小黄花 从出生那年就飘着')
}
}
对象的语法:花括号开头,花括号结束。{}(不知道为啥它叫花括号,百度也没百度到明确的指示)
2.2 创建对象
2.2.1 语法
- 注意:先学习对象的基本使用,再学习对象的类型注解(对象的类型注解类似于对象自身的语法)。
对象的语法:let person = {}
此处的 {} (花括号、大括号)表示对象。而对象中没有属性或方法时,称为:空对象。
对象中的属性或方法,采用 键值对 的形式,键、值之间使用冒号( : )来配对。
let person = {
键1: 值1,
键2: 值2
}
let person = {
name: '刘老师',
age: 18
}
键(key)—>名称 ,值(value)—->具体的数据。
多个键值对之间,通过逗号(,)来分隔(类比数组)。
2.2.2 方法与函数,区分
- 现在,对象person具有两个属性:
let person = { name: '刘老师', age: 18 }
属性和方法的区别:值是不是函数,如果是,就称为方法;否则,就是普通属性。
let person = {
sayHi: function () {
console.log('大家好,我是一个方法')
}
}
什么是值?
let person = {
键1: 值1,
键2: 值2
}
2.1 注意:函数用作方法时可以省略function后面的函数名称,也叫做匿名函数
2.2 函数没有名称,如何调用? 此处的sayHi相当于函数名称,将来通过对象的sayHi就可以调用了。
如果一个函数是单独出现的,没有与对象关联,我们称为函数;否则,称为方法。
2.3 问:谁是方法,谁是函数;
2.3.1
function x() {
console.log('大家好,我是一个方法')
}
2.3.2
y:function x() {
console.log('大家好,我是一个方法')
}
答:2.3.1 是函数,2.3.2 是方法;
以下为自己的想法:
- 函数就像一个个单独的方法,方法不在对象里面,就叫做函数;
- 当然不是这么笼统。函数和方法的创建的语法都是不一样的;
- 但从效果来看,方法有点像是把一个个函数集中起来的感觉。
2.2.3 总结
总结:
对象中的属性或方法,采用 键值对 的形式,因此,对象是无序键值对的集合。
- 使用什么符号创建对象? 花括号({})
- 键(key)、值(value)之间通过什么符号配对? 冒号(:)
- 多个属性或方法之间使用什么符号分隔? 逗号(,)
- 属性和方法的区别? 值是不是函数
2.3 接口
2.3.1 对象的类型注解
接口:为对象的类型注解命名,并为你的代码建立契约来约束对象的结构。
TS 中的对象是结构化的,结构简单来说就是对象有什么属性或方法。
在使用对象前,就可以根据需求,提前设计好对象的结构。
比如,创建一个对象,包含姓名、年龄两个属性。
思考过程:
1 对象的结构包含姓名、年龄两个属性
2 姓名→字符串类型,年龄 →数值类型
3 创建对象。
let person: {
name: string;
age: number;
}
→→
person = {
name: '刘老师',
age: 18
}
这就是对象的结构化类型(左侧),即:对该对象值(右侧)的结构进行类型约束。
或者说:建立一种契约,约束对象的结构。
2.4总结
总结:
TS 中的对象是结构化的,在使用对象前,就可以根据需求,提前设计好对象的结构。
这么说,还是可以不写结构注解咯;
对象的结构化类型(类型注解):建立一种契约,约束对象的结构。
注意点:类型注解中键值对的值为类型!
2.4 取值与存值
取值,即:拿到对象中的属性或方法并使用。
获取对象中的属性,称为:访问属性。
获取对象中的方法 并调用,称为:调用方法。
- 访问属性
let jay = { name: '周杰伦', height: 175 }
需求:获取到对象(jay)的name属性。
console.log(jay.name)
说明:通过点语法(.)就可以访问对象中的属性。
技巧:在输入点语法时,利用VSCode给出来的提示,利用上下键快速选择要访问的属性名称。
// 创建接口
interface IUser {
name: string
height: number
}
// 创建对象
let jay: IUser = {
name: '张虹成'
height: 175
}
// 访问对象jay的name属性
console.log(jay.name)
- 调用方法;
let jay = {
sing: function () {
console.log('故事的小黄花 从出生那年就飘着')
}
}
需求:调用对象(jay)的sing方法,让他唱歌。
jay.sing()
说明:通过点语法(.)就先拿到方法名称,然后,通过小括号调用方法。
用访问属性的例子
// 创建接口
interface IUser {
name: string
height: number
sing: () => viod
}
// 创建对象
let jay: IUser = {
name: '张虹成'
height: 175
sing: function (){
console.log('故事的小黄发。')
}
}
// 访问对象jay的name属性
console.log(jay.name)
console.log('我叫', jay.name)
// 调用方法
jay.sing()
- 补充说明:
console.log(参数1, 参数2, ...)
错可以多个
console.log(‘我叫’, jay.name)
ts-node xxx.ts 会打印出 我叫张虹成;
实际上,console是一个对象,而log是该对象提供的一个方法。
console这个对象,是浏览器环境提供的,所以可以直接用;
并且,log方法可以有多个参数。
console.log('我叫', jay.name)
3.1 不过这样打印出来的,之间会有一个空格,不想要空格,还是的用 “+”号
- 总结
通过什么符号,来访问对象中的属性或方法? 点语法(.)
注意:方法需要调用,所以,通过点语法拿到方法名称后,不要忘记使用小括号调用!
技巧:通过点语法,访问对象属性时,利用VSCode出来的提示,快速选择要访问的属性或方法。
该技巧很实用,特别是访问别人创建的对象时(比如:console对象)。
2. 存值
- 存值,即修改(设置)对象中属性的值
let jay = { name: '周杰伦', height: 175 }
需求:将对象(jay)的name属性的值修改为’周董’。
jay.name = '周董'
解释:先通过点语法获取到name属性,然后,将新值’周董’赋值给该属性。
console.log(jay.name) // 周董
注意:设置的新值,也必须符合该属性的类型要求!
注意:几乎不会修改对象中的方法。
3. 总结
对象是对现实生活中具体事物(特征和行为)的抽象,可以使用对象来描述这些具体的事物。
对象包含:1 属性 2 方法。
简单来说:对象就是无序键值对的集合。
对象是结构化的,它的类型注解就是从对象的结构(属性、方法)出发,进行类型约束和检查。
推荐:使用接口来作为对象的类型注解,建立一种契约,约束对象的结构。
TS中的数据类型分为两大类:1 原始类型(基本数据类型) 2 对象类型(复杂数据类型)。
常用的基本数据类型有 5 个: number / string / boolean / undefined / null。
复杂数据类型:object(对象、数组)、function(函数)。
3. TypeScript 之 Web开发
3.1 Web开发基础
下棋游戏(XXOO)是通过 Web(网页)开发实现的,因此,我们要学习 Web 开发的相关知识。
Web 开发涵盖以下内容:HTML、CSS、JavaScript (HTML、CSS不是本课程的重点,仅简单讲解)。
三者之间的关系:
- (结构)HTML 负责创建页面结构。
- (样式)CSS 负责美化页面结构(相当于化妆)。
- (行为)JavaScript 负责让页面“动”起来,解锁更多动效。
HTML(Hyper Text Markup Language,即:超文本标记语言)负责创建页面结构。
创建第一个 HTML 步骤:
- 快速生成 HTML 基本骨架:在文件中输入英文叹号(!),然后,按 tab 键。
- 创建 a .html 文件。
- 创建按钮标签:在 body 标签中,输入 button,按 tab 键。
- 打开 HTML 页面:在文件夹中找到页面文件,双击打开。
- 注意:页面中可见的内容,写在 body 标签中。
<div></div> 布局标签(独占一行)
<p></p> 段落标签(存放文字)
<h1></h1> 标题标签
<button></button> 按钮标签
<img src="" /> 图片标签
...
CSS(Cascading Style Sheets,即:层叠样式表)负责美化页面结构。
使用 CSS 的三种方式:
- style 属性:在 HTML 标签中,通过 style 属性来添加样式。
<p style="color: red; font-size: 50px;">天青色等烟雨 ...</p>
- style 标签:在 head 标签中,创建 style 标签。
<style>
/* 标签选择器 */
p { color: red; }
</style>
技巧: 先通过选择器获取标签,再设置样式。
常用的 CSS 选择器:
/* 标签选择器 */
p { color: red; }
/* id 选择器 */
#txt { font-size: 50px; }
/* 类(名)选择器 –- 推荐 */
.cls { backgroud-color: pink; }
推荐:使用 类选择器 来给标签添加样式!
- CSS 文件:创建 .css 文件,将样式放在该文件中,然后在 head 中通过 link 标签引入该文件。
<link ref="stylesheet" href="./index.css" />
总结:
作用:美化页面结构。
使用方式:
- HTML 标签的 style 属性。
- style 标签(在 head 标签中创建)。
- CSS 文件(在 head 中通过 link 标签引入)。
常用的 CSS 选择器:
p { color: red; } /* 标签选择器 */
#txt { font-size: 50px; } /* id 选择器 */
.class { backgroud-color: pink; } /* 类(名)选择器 –- 推荐 */
3.2 浏览器中运行TS
注意:浏览器中只能运行 JS, 无法直接运行 TS,因此,需要将 TS 转化为 JS 然后再运行。
浏览器中运行 TS 的步骤:
- 命令 tsc index.ts 将 ts 文件转化为 js 文件。
- 在页面中,使用 script 标签引入生成的 js 文件(注意是 js 文件)。
<script src="./index.js"></script>
问题:每次修改 ts 文件后,都要重新运行 tsc 命令将 ts 转化为 js 。
解决方式:使用 tsc 命令的监视模式。
tsc --watch index.ts
解释: –watch 表示启用监视模式,只要重新保存了 ts 文件,就会自动调用 tsc 将 ts 转化为 js。
3.3 DOM操作
1.DOM(Document Object Modal):文档对象模型
DOM 是浏览器提供的( 浏览器特有),专门用来 操作网页内容的一些 JS 对象。
HTML:超文本标记语言,用来创建网页结构。
目的:让我们可以使用 JS/TS 代码来操作页面(HTML)内容,让页面“动”起来,从而实现 Web 开发。
两者的关系:浏览器根据 HTML 内容创建相应的 DOM 对象,也就是:每个 HTML 标签都有对应的 DOM 对象
2. 学习四个常用 DOM 操作:1 .获取 DOM 元素(DOM 对象) 2 .设置样式 .设置内容 4 .绑定(解绑)事件。
DOM 操作的套路(技巧):先找人 后做事。
- 找人:获取 DOM 元素。
- 做事:设置样式、内容、绑定(解绑)事件。
document.title = '等你下课'
3.3.2 获取元素
常用方法有两个:
- querySelector(selector) 作用:获取某一个 DOM 元素。
- querySelectorAll(selector) 作用:同时获取多个 DOM 元素。
query; selector; query selector ;
- 获取一个DOM元素:
document.querySelector(selector)
document 对象:文档对象(整个页面),是操作页面内容的入口对象。
想操作页面内容,必须先拿到document对象;让我们回想一下对象的使用;
selector 参数:是一个 CSS 选择器(标签、类、id 选择器等)。
作用:查询(获取)与选择器参数匹配的 DOM 元素,但是,只能获取到第一个!
推荐:使用 id 选择器(唯一)。
let title = document.querySelector('#title')
解释:获取页面中id为title的DOM元素。
2. 类型断言
问题:调用 querySelector() 通过 id 选择器获取 DOM 元素时,拿到的元素类型都是 Element。
因为无法根据 id 来确定元素的类型,所以,该方法就返回了一个 宽泛的类型:元素(Element)类型。
不管是 h1 还是 img 都是元素。
导致新问题:无法访问 img 元素的 src 属性了。
因为:Element 类型只包含所有元素共有的属性和方法(比如:id 属性)。
在ts中,img.src 会报错。img.id,title.id 就不会;id是大家都有的,而有些是特有的
- 解决方式:使用类型断言,来手动指定 更 加具体的类型(比如,此处应该比 Element 类型更加具体)。
语法:值 as 更具体的类型
比如:let img = document.querySelector('#image') as HTMLImageElement
解释:我们确定 id=”image” 的元素是图片元素,所以,我们将类型指定为 HTMLImageElement。
我们怎么知道什么元素是什么类型呢?
技巧:通过 console.dir() 打印 DOM 元素,在属性的最后面,即可看到该元素的类型。
3. 获取多个元素
document.querySelectorAll(selector)
作用:获取所有与选择器参数匹配的 DOM 元素,返回值是一个列表。
推荐:使用 class 选择器。
示例:
let list = document.querySelectorAll('.a')
解释:获取页面中所有 class 属性包含 a 的元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p class="a">1</p>
<p class="b a">2</p>
<p class="a c">3</p>
<p class="c a b">4</p>
<script src="./index.js"></script>
</body>
</html>
// 示例:获取带有.a类名的元素列表
let list = document.querySelectorAll('.a')
console.log(list)
3.3.3 操作文本内容
-
读取
dom.innerText
-
设置
dom.innerText = '等你下课'
注意:需要通过类型断言来指定 DOM 元素的具体类型,才可以使用 innerText 属性。
注意:设置内容时,会 覆盖原来的内容。如何实现追加内容(比如,张虹成 → 张虹成– 彭华)?
dom.innerText = dom.innerText + ' – 彭华'
// 简化
dome.innerText += ' – 彭华'
- 练习:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Document</title>
</head>
<body>
<h2>xxxooo</h2>
<h3>试试?</h3>
<h4>再试试?</h4>
<p class="a">1</p>
<p class="b a">2</p>
<p class="a c">3</p>
<p class="c a b">4</p>
<script src="./index.js"></script>
</body>
</html>
/*
获取元素 和 innerText
要求: 给所有 P 标签的内容前面,添加 '[自己的索引]'
1 → [0]1 2 → [1]2
*/
// 1. 获取所有的P元素列表(可以遍历)
let list = document.querySelectorAll('.a')
// console.log(list) // 看看效果
// 2. 遍历p元素列表,拿到每一个p元素以及索引号
list.forEach(function (item, index){
console.log(item, index)
// 此时可以在浏览器F12的console里面打开打印出来的 元素 与 索引号
// 此时的item 是 Element 类型
// 因需要访问item(P 元素)的 innerText 属性,所以要 类型断言 指定更加具体的类型
let p = item as HTMLParagraphElement
// 3. 通过索引号拼接内容,然后甚至文本内容
p.innerText = '[' + index + ']' + p.innerText
//现在访问的是p,不是item;为什么不是item?
//item只是是个参数,因为一系列逻辑函数而获取了innerText,实则无法改变item;
})
3. 总结
总结:
类样式(classList)的操作有三种:
// 添加
dom.classList.add('a', 'b')
// 移除
dom.classList.remove('b', 'c')
// 判断是否存在
let has = dom.classList.contains('a')