文章目录
- 内置对象
- 1 解构赋值
- 1.1 保留默认值
- 1.2 接受剩余的所有参数
- 1.3 对函数执行结果解构
- 1.4 交换两个变量的值
- 1.5 二维数组结构
- 2 对象的解构
- 2.1 声明对象同时解构对象
- 2.2 先声明再解构
- 2.3 解构不存在的属性
- 2.4 设置解构别名
- 2.5 设置解构默认值
- 3 对象的序列化
- 3.1 对象的序列化
- 3.2 序列化的作用
- 3.3 如何进行序列化
- 3.4 编写JSON的注意事项
- 4 Map
- 4.1 Map介绍
- 4.2 创建一个Map
- 4.3 常用方法介绍
- 4.4 将Map转换为数组
- 4.5 从数组构建Map
- 4.6 遍历Map
- 5 Set
- 5.1 Set介绍
- 5.2 创建Set
- 5.3 方法
- 5.4 遍历Set
- 5.5 利用Set对数组去重
- 6 Math
- 6.1 Math介绍
- 6.2 常用的常量和方法
- 6.3 混合使用
- 7 Date
- 7.1 Date介绍
- 7.2 常用方法介绍
- 7.3 创建指定日期的Date对象
- 7.4 日期的格式化
- 8 包装类
- 9 字符串的方法
- 9.1 length
- 9.2 索引
- 9.3 str.at()
- 9.4 str.charAt()
- 9.5 str.concat()
- 9.6 str.includes()
- 9.7 str.indexOf() 和 str.lastIndexOf()
- 9.8 str.startsWith() 和 str.endsWith()
- 9.9 str.padStart() 和 str.padEnd()
- 9.10 str.replace() 和 str.replaceAll()
- 9.11 str.slice() 和 str.substring()
- 9.12 str.split() 和 str.join()
- 9.13 str.toLowerCase() 和 str.toUpperCase()
- 9.14 str.trim() 和 str.trimStart() 和 str.trimEnd()
- 9.15 str.search()
- 9.16 str.match() 和 str.matchAll()
- 10 正则表达式
- 10.1 正则表达式的介绍
- 10.2 创建正则表达式
- 10.3 通过整个表达式检查字符串是否符合规则
- 10.4 正则表达式的基本语法
- 10.5 提取符合规则的字符串
- 10.6 例子
- 11 垃圾回收
内置对象
这部分内容开始对JS中其他的内建对象进行补充。主要包括:结构复制、序列化、Map、Set、Date、包装类、String、正则表达式以及垃圾回收(GC)
1 解构赋值
案例:将arr分别赋值给a,b,c
基本方法:
const arr = ["孙悟空", "猪八戒", "沙和尚"]
let a,
b,
c
a = arr[0]
b = arr[1]
c = arr[2]
console.log(a,b,c)
使用对象解构:
推荐在结构赋值前面手动加分号,防止编译器解析出问题
const arr = ["孙悟空", "猪八戒", "沙和尚"]
let a,
b,
c
;[a, b, c] = arr // 解构赋值
console.log(a,b,c)
但是一般使用的时候是声明和赋值在一起的(声明同时结构),但是如果前面参数比后面数组多,会被赋值undefined
let [d, e, f, g] = ["唐僧", "白骨精", "蜘蛛精", "玉兔精"]
console.log(d, e, f, g)
;[d, e, f, g] = ["唐僧", "白骨精", "蜘蛛精"]
console.log(d, e, f, g)
在赋值的时候给定默认值,就可以防止其出现undefined,如果设置了默认值,同时在数组解构的时候可以覆盖掉这个值,那么最终这个值存的是数组中的对应元素
有值就赋值,没有值就用默认值
;[d, e, f=73, g=10] = ["唐僧", "白骨精", "蜘蛛精"]
console.log(d, e, f, g)
1.1 保留默认值
在上面的例子中,g开始有值,但是在结构后又变成undefined了,我们想要的效果是如果可以赋值就赋值,不能赋值就用原来的,这样就可以通过下面这样设置来达到效果
let [d, e, f, g] = ["唐僧", "白骨精", "蜘蛛精", "玉兔精"]
console.log(d, e, f, g)
;[d, e, f, g=g] = ["唐僧", "白骨精", "蜘蛛精"]
console.log(d, e, f, g)
1.2 接受剩余的所有参数
解构数组时,可以使用…来设置获取多余的元素
let [n1, n2, ...n3] = [4, 5, 6, 7]
console.log(n1, n2, n3)
1.3 对函数执行结果解构
function fn() {
return ["二郎神", "猪八戒"]
}
let [name1, name2] = fn() // "二郎神", "猪八戒"
1.4 交换两个变量的值
let a1 = 10
let a2 = 20
// 原来的做法
let temp = a1
a1 = a2
a2 = temp
// 解构赋值
;[a1, a2] = [a2, a1] // [20, 10]
交换数组中两个元素的位置
const arr2 = ["孙悟空", "猪八戒"]
;[arr2[0], arr2[1]] = [arr2[1], arr2[0]]
1.5 二维数组结构
const arr3 = [["孙悟空", 18, "男"], ["猪八戒", 28, "男"]]
let [[name, age, gender], obj] = arr3
console.log(name, age, gender)
console.log(obj)
2 对象的解构
2.1 声明对象同时解构对象
const obj = { name: "孙悟空", age: 18, gender: "男" }
let { name, age, gender } = obj // 声明变量同时解构对象
console.log( name, age, gender)
2.2 先声明再解构
这个必须得在解构的时候用括号括起来,不然会将大括号解析为代码块,然后会报错
const obj = {name: "孙悟空", age: 18, gender: "男"}
let name, age, gender
;({name, age, gender} = obj)
console.log( name, age, gender)
2.3 解构不存在的属性
const obj = { name: "孙悟空", age: 18, gender: "男" }
let { address } = obj
console.log(address)
2.4 设置解构别名
const obj = { name: "孙悟空", age: 18, gender: "男" }
// 设置别名
let {name: a, age: b, gender: c} = obj
console.log(a, b, c)
2.5 设置解构默认值
const obj = { name: "孙悟空", age: 18, gender: "男" }
// 设置默认值
let {name: a, age: b, gender: c, address: d = "花果山"} = obj
console.log(a, b, c, d)
3 对象的序列化
3.1 对象的序列化
- JS中的对象使用时都是存在于计算机的内存中的
- 序列化指将对象转换为一个可以存储的格式,在JS中对象的序列化通常是将一个对象转换为字符串(JSON字符串)
3.2 序列化的作用
- 对象转换为字符串后,可以将字符串在不同的语言之间进行传递,甚至人可以直接对字符串进行读写操作,使得JS对象可以不同的语言之间传递
- 用途:
- 作为数据交换的格式
- 用来编写配置文字
3.3 如何进行序列化
- 在JS中有一个工具类 JSON (JavaScript Object Notation) JS对象表示法
- JS对象序列化后会转换为一个字符串,这个字符串我们称其为JSON字符串
const obj = {
name: "孙悟空",
age: 18,
}
// 将obj转换为JSON字符串
const str = JSON.stringify(obj) //JSON.stringify() 可以将一个对象转换为JSON字符串
const obj2 = JSON.parse(str) // JSON.parse() 可以将一个JSON格式的字符串转换为JS对象
console.log(typeof str, str)
console.log(typeof obj2, obj2)
3.4 编写JSON的注意事项
- JSON字符串有两种类型:
- JSON对象 {}
- JSON数组 []
- JSON字符串的属性名必须使用双引号引起来
- JSON中可以使用的属性值(元素)
- 数字(Number)
- 字符串(String) 必须使用双引号,不要使用单引号,单引号在其他语言可能不表示字符串
- 布尔值(Boolean)
- 空值(Null)
- 对象(Object {})
- 数组(Array [])
- JSON的格式和JS对象的格式基本上一致的,注意:JSON字符串如果属性是最后一个,则不要再加
,
4 Map
4.1 Map介绍
- Map用来存储键值对结构的数据**(key-value)**
- Object中存储的数据就可以认为是一种键值对结构
- Map和Object的主要区别:
- Object中的属性名只能是字符串或符号,如果传递了一个其他类型的属性名,JS解释器会自动将其转换为字符串
- Map中任何类型的值都可以成为数据的key
const obj = {
"name":"孙悟空",
'age':18,
[Symbol()]:"哈哈",
[obj2]:"嘻嘻"
}
4.2 创建一个Map
const map = new Map()
map.set("name", "孙悟空")
map.set(obj2, "呵呵")
map.set(NaN, "哈哈哈")
map.delete(NaN)
// map.clear()
console.log(map)
console.log(map.get("name"))
console.log(map.has("name"))
4.3 常用方法介绍
map.size()
获取map中键值对的数量map.set(key, value)
向map中添加键值对map.get(key)
根据key获取值map.delete(key)
删除指定数据map.has(key)
检查map中是否包含指定键map.clear()
删除全部的键值对map.keys()
获取map的所有的keymap.values()
获取map的所有的value
4.4 将Map转换为数组
方法一:使用方法Array.from(map)
const map = new Map()
map.set("name", "孙悟空")
map.set("age", 18)
map.set({}, "呵呵")
// 将map转换为数组
const arr = Array.from(map) // [["name","孙悟空"],["age",18]]
const arr = [...map]
console.log(arr)
方法二:使用解构符
推荐这种方法,写法更简便
const map = new Map()
map.set("name", "孙悟空")
map.set("age", 18)
map.set({}, "呵呵")
// 将map转换为数组
const arr = [...map]
console.log(arr)
4.5 从数组构建Map
const map2 = new Map([
["name", "猪八戒"],
["age", 18],
[{}, () => {}],
])
console.log(map2)
4.6 遍历Map
方法一:使用for-of
const map = new Map()
map.set("name", "孙悟空")
map.set("age", 18)
map.set({}, "呵呵")
for (const [key, value] of map) {
// const [key, value] = entry
console.log(key, value)
}
方法二:使用forEach
const map = new Map()
map.set("name", "孙悟空")
map.set("age", 18)
map.set({}, "呵呵")
map.forEach((key, value)=>{
console.log(key, value)
})
5 Set
5.1 Set介绍
- Set用来创建一个集合
- 它的功能和数组类似,不同点在于Set中不能存储重复的数据
- Set存储元素是无序的,不能通过下标访问
5.2 创建Set
new Set()
:构造空Setnew Set([...])
:从数组构造
const set = new Set()
// 向set中添加数据
set.add(10)
set.add("孙悟空")
set.add(10)
console.log(set)
5.3 方法
size()
获取数量add()
添加元素has()
检查元素delete()
删除元素
5.4 遍历Set
方法一:for-of
const set = new Set()
// 向set中添加数据
set.add(10)
set.add("孙悟空")
set.add(10)
for (const item of set) {
console.log(item)
}
方法二:forEach
const set = new Set()
// 向set中添加数据
set.add(10)
set.add("孙悟空")
set.add(10)
set.forEach(item => {
console.log(item)
})
5.5 利用Set对数组去重
const arr2 = [1, 2, 3, 2, 1, 3, 4, 5, 4, 6, 7, 7, 8, 9, 10]
const set2 = new Set(arr2)
console.log([...set2])
6 Math
Math - JavaScript
6.1 Math介绍
- Math一个工具类
- Math中为我们提供了数学运算相关的一些常量和方法
6.2 常用的常量和方法
-
常量:
Math.PI
圆周率Math.e
自然对数
-
方法:
-
Math.abs()
求一个数的绝对值 -
Math.min()
求多个值中的最小值 -
Math.max()
求多个值中的最大值 -
Math.pow()
求x的y次幂 -
Math.sqrt()
求一个数的平方根 -
Math.floor()
向下取整 -
Math.ceil()
向上取整 -
Math.round()
四舍五入取整 -
Math.trunc()
直接去除小数位 -
Math.random()
生成一个0-1之间的随机数(前开后闭)
-
let result = Math.abs(10)
result = Math.abs(-10)
result = Math.min(10, 20, 30, 44, 55, -1)
result = Math.max(10, 20, 30, 44, 55, -1)
result = Math.pow(4, 2) // 4 ** 2
result = Math.sqrt(4) // 4 ** .5
result = Math.floor(1.2)
result = Math.ceil(1.2)
result = Math.round(1.4)
result = Math.trunc(1.5)
6.3 混合使用
- 生成 0-x之间的随机数:
Math.round(Math.random() * x)
Math.floor(Math.random() * (x + 1))
- 生成 x-y 之间的随机数
Math.round(Math.random() * (y-x) + x)
// 生成0-5之间的整数
result = Math.round(Math.random() * 5)
// 生成11-20之间的整数
result = Math.round(Math.random() * 9 + 11)
7 Date
Date - JavaScript
7.1 Date介绍
- 在JS中所有的和时间相关的数据都由Date对象来表示
创建Date对象
let d = new Date() // 直接通过new Date()创建时间对象时,它创建的是当前的时间的对象
console.log(d)
7.2 常用方法介绍
getFullYear()
获取4位年份getMonth()
返当前日期的月份(0-11)getDate()
返回当前是几日getDay()
返回当前日期是周几(0-6) 0表示周日getHours
返回当前小时getMinutes
返回当前分钟getSeconds
返回秒getTime()
返回当前日期对象的时间戳- 时间戳:自1970年1月1日0时0分0秒到当前时间所经历的毫秒数
- 计算机底层存储时间时,使用都是时间戳
- Date.now() 获取当前的时间戳
7.3 创建指定日期的Date对象
方法一
// 月/日/年 时:分:秒
let d = new Date("12/20/1998")
console.log(d)
方法二
// 年-月-日T时:分:秒
let d = new Date("2020-12-30")
console.log(d)
方法三
推荐使用这种方式创建
月从0开始记数
至少需要传两个参数
// new Date(年份, 月, 日, 时, 分, 秒, 毫秒)
let d = new Date(2020, 0, 1, 13, 45, 33)
console.log(d)
方法四
使用时间戳
let timeNow = new Date().getTime()
console.log(timeNow) // 获取当前的时间戳
let d = new Date(timeNow)
console.log(d)
7.4 日期的格式化
// 将日期转换为本地的字符串
console.log(d.toLocaleDateString())
// 将时间转换为本地的字符串
console.log(d.toLocaleTimeString())
// 将时间日期都转
console.log(d.toLocaleString())
toLocaleString()
-
可以将一个日期转换为本地时间格式的字符串
-
参数
-
描述语言和国家信息的字符串
- zh-CN 中文中国
- zh-HK 中文香港
- en-US 英文美国
-
需要一个对象作为参数,在对象中可以通过对象的属性来对日期的格式进行配置
配置文档
- dateStyle 日期的风格
- timeStyle 时间的风格
- full
- long
- medium
- short
- hour12 是否采用12小时值
- true
- false
- weekday 星期的显示方式
"long"
(e.g.,Thursday
)"short"
(e.g.,Thu
)"narrow"
(e.g.,T
). Two weekdays may have the same narrow style for some locales (e.g.Tuesday
’s narrow style is alsoT
).
- year
"numeric"
(e.g.,2012
)"2-digit"
(e.g.,12
)
- month
"numeric"
(e.g.,3
)"2-digit"
(e.g.,03
)"long"
(e.g.,March
)"short"
(e.g.,Mar
)"narrow"
(e.g.,M
). Two months may have the same narrow style for some locales (e.g.May
’s narrow style is alsoM
).
- day
"numeric"
(e.g.,1
)"2-digit"
(e.g.,01
)
-
8 包装类
在JS中,除了直接创建原始值外,也可以创建原始值的对象,也就是通过对象的时候去创建原始值
- 通过
new String()
可以创建String类型的对象 - 通过
new Number()
可以创建Number类型的对象 - 通过
new Boolean()
可以创建Boolean类型的对象
但是千万不要这么做
let str = new String("hello")
let num = new Number(11)
let bool = new Boolean(true)
let bool2 = new Boolean(true)
console.log(bool == bool2)
上面这种情况比较的是两个对象,所以比较的就是地址,调用两次new创建的对象肯定不是指向同一对象,所以尽量不要使用这种方式
JS中一共有五个包装类
String
--> 字符串包装为String对象Number
--> 数值包装为Number对象Boolean
--> 布尔值包装为Boolean对象BigInt
--> 大整数包装为BigInt对象Symbol
--> 符号包装为Symbol对象
通过包装类可以将一个原始值包装为一个对象,当我们对一个原始值调用方法或属性时,JS解释器会临时将原始值包装为对应的对象,然后调用这个对象的属性或方法
由于原始值会被临时转换为对应的对象,这就意味着对象中的方法都可以直接通过原始值来调用
这个功能是留给js自己处理的,尽量不要自己调用new生成新对象
let num = 11
num = num.toString()
console.log(num)
9 字符串的方法
String文档
字符串其本质就是一个字符数组,所以字符串的很多方法都和数组是非常类似的
"hello" --> ["h", "e", "l", "l", "o"]
9.1 length
length
获取字符串的长度
let str = "hello"
str.length
9.2 索引
字符串[索引] 获取指定位置的字符
let str = "hello"
str[1]
9.3 str.at()
根据索引获取字符,可以接受负索引
let str = "hello"
console.log(str.at(0))
console.log(str.at(-1))
console.log(str.at(-2))
9.4 str.charAt()
根据索引获取字符
不支持负数,传入负数返回的是空串
let str = "hello"
console.log(str.charAt(0))
9.5 str.concat()
用来连接两个或多个字符串
不会破坏原来的字符串,会生成新字符串
和
+
效果一样,推荐使用+
let str = "hello"
console.log(str.concat(" ", "world"))
9.6 str.includes()
- 用来检查字符串中是否包含某个内容(字符串)
- 有返回true
- 没有返回false
- 第一个参数是要找的内容
- 第二个参数是查找的起始位置
let str = "hello hello how are you"
console.log(str.includes("hello"))
console.log(str.includes("ttt"))
console.log(str.includes("hello", 10))
9.7 str.indexOf() 和 str.lastIndexOf()
查询字符串中是否包含某个内容,并返回下标,如果没有的话返回-1
第二个参数是查找的起始,不传默认为0
let str = "hello hello how are you"
9.8 str.startsWith() 和 str.endsWith()
检查一个字符串是否以指定内容开头或者结尾的
let str = "hello hello how are you"
9.9 str.padStart() 和 str.padEnd()
通过在开头或者结尾添加指定的内容,使字符串保持某个长度
- 第一个参数是字符串的位数
- 第二个参数是要补的符号
如果穿进去的第一个参数比
str.length
少,则不做任何操作
str = "100"
console.log(str.padStart(7, "0"))
console.log(str.padEnd(7, "0"))
9.10 str.replace() 和 str.replaceAll()
使用一个新字符串替换一个指定内容
str = "hello hello how are you"
let result = str.replace("hello", "abc")
console.log(result)
str = "hello hello how are you"
result = str.replaceAll("hello", "abc")
console.log(result)
使用正则表达式替换
通过指定模式
g
可以实现全部替换
9.11 str.slice() 和 str.substring()
对字符串进行切片
- 第一个参数是开始位置
- 第二个参数是结束位置
- 前闭后开
substring会自动判断参数,如果第一个参数比第二个参数大,则会自动交换参数位置,slice不会
str = "hello hello how are you"
result = str.slice(12, 15)
result = str.slice(15, 12)
result = str.substring(12, 15)
result = str.substring(15, 12)
9.12 str.split() 和 str.join()
str.split()
:用来将一个字符串拆分为一个数组
str.join()
:用来将数组拼接为字符串
- 参数是分割的符号,也可以根据正则表达式拆分
str = "abc@bcd@efg@jqk"
result = str.split("@")
result = result.join("@"")
根据正则表达式拆分
9.13 str.toLowerCase() 和 str.toUpperCase()
将字符串转为大写或小写
str = "abcdABCD"
result = str.toLowerCase()
result = result.toUpperCase()
9.14 str.trim() 和 str.trimStart() 和 str.trimEnd()
str.trim()
:去除字符串的前后空格str.trimStart()
:去除开始空格str.trimEnd()
:去除结束空格
str = " ab c "
str.trim()
str.trimStart()
str.trimEnd()
9.15 str.search()
可以去搜索符合正则表达式的内容第一次在字符串中出现的位置
9.16 str.match() 和 str.matchAll()
str.match()
:根据正则表达式去匹配字符串中符合要求的内容str.matchAll()
:根据正则表达式去匹配字符串中符合要求的内容(必须设置g 全局匹配),返回的是一个迭代器
str.match()
可以通过设置全局模式g
来匹配所有符合的字符串,并以数组的形式返回
str.matchAll()
如果不使用全局模式的话会报错,返回的是一个迭代器,使用for-of
遍历可以打印结果
10 正则表达式
10.1 正则表达式的介绍
- 正则表达式用来定义一个规则
- 通过这个规则计算机可以检查一个字符串是否符合规则或者将字符串中符合规则的内容提取出来
- 正则表达式也是JS中的一个对象,所以要使用正则表达式,需要先创建正则表达式的对象
- typeof 返回的是object
10.2 创建正则表达式
通过构造函数创建:new RegExp()
可以接收两个参数(字符串) 1.正则表达式 2.匹配模式
使用这种方式js编译器会自动将我们的这种写法去转化和字面量相同的方式
优势:可以传递变量,动态生成自责表达式
let reg = new RegExp("a", "i") // 通过构造函数来创建一个正则表达式的对象
console.log(reg)
使用字面量来创建:
// 创建和上面相同的正则
let reg = /a/i
console.log(reg)
使用构造函数的形式需要考虑转义字符,在字面量中可以直接写
let reg = /\w/
reg = new RegExp("\\w") // 如果只写 \w 的话会转义成 w,就表示字母w
10.3 通过整个表达式检查字符串是否符合规则
let str = "a"
let reg = new RegExp("a")// 表示检查一个字符串中是否含有a
// let reg = /a/ // 也可以使用这种方式定义
let result = reg.test(str) // true
result = reg.test("b") // false
result = reg.test("abc") // true
result = reg.test("bcabc") // true
10.4 正则表达式的基本语法
-
在正则表达式中大部分字符都可以直接写
-
| 在正则表达式中表示或(整体的或)
/abc|bcd/
表示有abc或者bcd这两个字符串
-
[] 表示或(字符集)
- [a-z] 任意的小写字母
- [A-Z] 任意的大写字母
- [a-zA-Z] 任意的字母
- [0-9]任意数字
-
[^]
表示除了[^x]
除了x
-
.
表示除了换行外的任意字符 -
在正则表达式中使用
\
作为转义字符 -
使用括号进行分组
-
其他的字符集
-
\w 任意的单词字符,相当于
[A-Za-z0-9_]
-
\W 除了单词字符,相当于
[^A-Za-z0-9_]
-
\d 任意数字,相当于
[0-9]
-
\D 除了数字,相当于
[^0-9]
-
\s 空格
-
\S 除了空格
-
\b 单词边界
-
\B 除了单词边界
-
-
开头和结尾
-
^ 表示字符串的开头
-
$ 表示字符串的结尾例子
-
-
量词
- 只对前面紧接的一个字符起作用
- {m} 正好m个
- {m,} 至少m个
- {m,n} m-n个
+
一个以上,相当于{1,}*
任意数量的a?
0-1次,相当于{0,1}
10.5 提取符合规则的字符串
使用re.exec()
获取字符串中符合正则表达式的内容
案例:对于str = "abcaecafcacc"
提取出str中符合axc
格式的内容
默认情况下只会匹配第一个,通过设置模式
g
来开启全局匹配
let str = "abcaecafcacc"
let re = /a([a-z])c/g
let result = re.exec(str)
console.log(result)
不开启全局匹配g
模式,每次匹配的都是第一个
开启全局匹配g
模式:从头一直匹配到尾
在正则表达式中添加括号表示分组,因此我们现在可以拿到中间的字母(返回数组的第二个元素):
如果有多个括号的话,返回的顺序是按照左括号出现的顺序返回的
获取所有的匹配到的结果,使用循环可以实现
let str = "abcaecafcacc"
let re = /a([a-z])c/g
let result = re.exec(str)
while(result){
console.log(result[0], result[1])
result = re.exec(str)
}
10.6 例子
- 检查字符串中有没有字符串ab
re = /ab/
re.test("abc")
- 检查字符串中有没有a或b
方法一:使用|
方法二:使用[]
- 检查字符串中有没有小写字母
- 检查字符串中有没有除了小写字母之外的符号
- 检查字符串中是否以m开头或者结尾
- 检查字符串是不是abc
- 检查字符串中是否有连续出现三次ab
11 垃圾回收
垃圾回收(Garbage collection,gc)
- 和生活一样,生活时间长了以后会产生生活垃圾,程序运行一段时间后也会产生垃圾
- 在程序的世界中,什么是垃圾?
- 如果一个对象没有任何的变量对其进行引用,那么这个对象就是一个垃圾
- 垃圾对象的存在,会严重的影响程序的性能
- 在JS中有自动的垃圾回收机制,这些垃圾对象会被解释器自动回收,我们无需手动处理
- 对于垃圾回收来说,我们唯一能做的事情就是将不再使用的变量设置为null