九. 内置对象
1. 数组的解构
` const arr = ["孙悟空", "猪八戒", "沙和尚"]
let a, b, c
// a = arr[0]
// b = arr[1]
// c = arr[2]
;[a, b, c] = arr // 解构赋值
let [d, e, f, g] = ["唐僧", "白骨精", "只猪精", "玉兔精"] // 声明同时解构
console.log(d, e, f, g)
// ;[d, e, f, g] = [1, 2, 3]
;[d = 22, e = 22, f = 22, g = g] = [1, 2, 3]
let [n1, n2, ...n3] = [4, 5, 6, 7] // 解构数组时, 可以使用...来设置获取多余的元素
console.log(n1, n2, n3)
// console.log(d, e, f, g)
function fn() {
return ["二郎神", "猪八戒"]
}
let [name1, name2] = fn()
// fn()
console.log(name1, name2)
// 可以通过解构赋值快速交换两个变量的值
let a1 = 10
let a2 = 20
// let temp = a1
// a1 = a2
// a2 = temp
;[a1, a2] = [a2, a1]
const arr2 = ["孙悟空", "猪八戒"]
// console.log(arr2)
;[arr2[0], arr2[1]] = [arr2[1], arr2[0]]
// console.log(arr2)
- 数组中可以存储任意类型的数据, 也可以存数组
- 如果一个数组中的元素还是数组, 则这个数组我们就称为二维数组
const arr3 = [["孙悟空", 18, "男"], ["猪八戒", 28, "男"]]
// console.log(arr3)
// for (let stu of arr3) {
// for (let v of stu) {
// console.log(v)
// }
// console.log(stu)
// }
let [[name, age, gender], obj] = arr3
console.log(name, age, gender)
console.log(obj)
2. 对象的解构
const obj = { name: "孙悟空", age: 18, gender: "男" }
// let {name, age, gender} = obj // 声明变量同时解构对象
let name, age, gender
({ name, age, gender } = obj) // 加上括号可以, 要么报错
let { address } = obj // 没有的属性返回undefined
// console.log(address)
// console.log(name,age, gender)
// onj里面的name赋值给a 以此类推 别名
let { name: a, age: b, gender: c, address:d="花果山" } = obj
console.log(a, b, c, d)
3. 对象的序列化
- 对象的序列化
- JS中的对象在使用时都存在于计算机的内存中的
- 序列化指将对象转换为一个可以存储的格式
- 在JS中对象的序列化通常是将一个对象转换为字符串 (JSON字符串)
-
序列化用途 (对象转换为字符串有什么用)
-
对象转换为字符串后, 可以将字符串在不同语言间进行传递,
-
甚至人可以直接对字符串读写操作, 使得JS对象可以不同语言之间传递
-
用途:
- 作为数据交换的格式
- 用来编写配置文件
-
如何进行序列化:
-
在JS中有一个工具类 JSON (JavaScript Object Notation) JS对象表示法
-
JS对象序列化后, 会转换一个字符串, 这个字符串称为JSON字符串
-
-
也可以手动的编写JSON字符串, 很多程序的配合文件使用的就是JSON编写的
-
编写JSON注意事项
- JSON字符串有两种类型:
JSON对象 {}
JSON数组 [] - JSON字符串的属性名必须使用双引号引起来
- JSON可以使用的属性值(元素)
- 数字 (Number)
- 字符串 (String) 必须使用双引号
- 布尔值 (Boolean)
- 空值 (Null) undefined不支持
- 对象 (Object)
- 数组 (Array)
- JSON的格式和对象的格式基本是一致的,
注意: 但是JSON字符串如果属性是最后一个, 则不要在加逗号(,)
- 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(obj)
// console.log(str) // {"name":"孙悟空","age":18}
// console.log(obj2)
const str2 = '{"name": "猪八戒", "age": 28}'
const str3 = '{}'
const str4 = '["hello", true, null, 18, {}]'
console.log(str2)
4. JSON深拷贝
const obj = {
name: "孙悟空",
friend: {
name: "猪八戒"
}
}
// 对obj进行浅复制
const obj2 = Object.assign({}, obj)
// 对obj进行深复制
const obj3 = structuredClone(obj)
// console.log(obj)
// JSON进行深复制
const str = JSON.stringify(obj)
const obj4 = JSON.parse(str)
const obj5 = JSON.parse(JSON.stringify(obj)) // 上面代码合并
- Map
- Map用来存储键值对结构的数据 (key-value) 键值对的意思
- Object中存储的数据就可以认定为键值对结构
- Map和Object的主要区别:
-
Object中它的属性名只能是字符串或符号, 如果传递了一个非字符串, 其他类型的属性名
-
JS解释器会自动将其转换为字符串
-
Map中任何类型的值都可以成为数据的key
-
const obj2 = {}
const obj = {
"name": "孙悟空",
'age': 18,
[Symbol()]: "哈哈哈",
[obj2]: "嘻嘻"
}
- 创建
- new Map()
- 属性和方法
- map.size()获取map中键值对的数量
- map.set(key, value), 向map中添加键值对
- map.get(key), 根据key获取值
- map.delete(key), 删除指定的key数据
- map.has(key) 检查map中是否包含指定的键
- map.clear() 删除全部的键值对
// 创建Map
const map = new Map()
map.set("name", "孙悟空")
map.set(obj2, "呵呵")
map.set(NaN, "哈哈哈")
map.has("nane")
map.delete(NaN)
map.clear()
console.log(map)
// 取值
// console.log(map.get('name'))
const map = new Map()
map.set("name", "孙悟空")
map.set("age", 18)
map.set({}, "哈哈哈")
// 将map转换为数组
// const arr = Array.from(map) // [["nane", "孙悟空"], ["age", 18]]
// const arr = [...map] // 推荐使用
const map2 = new Map([["name", "猪八戒"], ["age", 18], [{}, () => {}]])
// console.log(map2)
// 遍历
// for(entry of map) {
// const [key, value] = entry
// console.log(entry, key, value)
// }
// 解构
// for([key, value] of map) {
// console.log(key, value)
// }
// 第三个值是map本身
// map.forEach((key, value, map) => {
// console.log(key, value)
// })
/*
map.keys() - 获取map的所有key
map.values() - 获取map中所有的value
*/
// 只获取所有的key value同样这样
for(key of map.keys()) {
console.log(key)
}
// 获取所有的键值对 map.entries() 一般不会用
7. Set
- Set
-
Set用来创建一个集合, 它的功能和数组类似
-
它的功能和数组类似, 不同点在于Set中不能存储重复的数据
-
使用方式
- 创建
- new Ste()
- new Ste([…])
- 方法
- size 获取数量
- add 添加元素
- has 检查元素
- delete 删除元素
- 创建
-
// 创建set
const set = new Set()
// 向set中添加数据
set.add(10)
set.add("孙悟空")
// set.add(10) // 存不进去 因为上面有10了
// console.log(set)
// 遍历
// for (item of set) {
// console.log(item)
// }
// 转为数组
const arr = [...set]
// console.log(arr)
const arr2 = [1,2,3,2,1,3,4,5,4,6,7,7,8,9,10]
// 数组去重先转换为set
const set2 = new Set(arr2)
// set转换为数组
console.log([...set2])
8. Math
-
PI就是常量 因为都是大写
-
Math
- Math一个工具类
- Math中为我们提供了数学运算相关的常量和方法
-
常量:
- Math.PI 圆周率
-
方法:
- Math.abs() 求一个数的绝对值 去除符号
-
Math.min() 求多个值中的最小值
-
Math.max() 求多个值中的最大值
-
Math.pow() 求x的y次幂
-
Math.sqrt() 求一个数的开方 求一个数的平方根
-
Math.floor() 向下取整
-
Math.ceil() 向上取整
-
Math.round() 四舍五入取整
-
Math.trunc() 去掉小数点
-
Matn.random() 生成一个0 - 1 的随机数 0到1 包括0 不包括1
-
- Math.abs() 求一个数的绝对值 去除符号
// console.log(Math.PI) 3.1415926
let result = Math.abs(-10) // 10
result = Math.min(10, 20, 30, 5, 5, 4) // 4
result = Math.max(10, 20, 30, 5, 5, 4) // 30
result = Math.pow(4, 4) // 等价于 4 ** 4
result = Math.sqrt(4) // 4 ** .5 开方
result = Math.floor(1.7)
// result = Math.floor(Math.random() * 100)
for (let i = 0; i < 50; i++) {
// 生成 0 - x之间的随机数
// result = Math.round(Math.random()* x)
// result = Math.floor(Math.random() * (x + 1))
// 生成一个x到y之间的随机数
// result = Math.round(Math.random() * (y - x) + x)
// 生成 0- 5之间的随机数
// result = Math.round(Math.random()* 5)
// result = Math.floor(Math.random() * 6)
// 1 - 6 之间的随机数
// result = Math.round(Math.random() * 5 + 1)
// 11 - 20之间的随机数
result = Math.round(Math.random() * (20 - 11) + 11)
console.log(result)
}
// console.log(result)
9. Date
- Date
- 在JS中所有的事件相关的数据都由Date对象来表示
- 对象的方法:
- getFullYear() 获取4位年份
- getMonth() 返回当前日期的月份 0 - 11 需要用需要 + 1
- getDate() 获取日期
- getDay() 返回当前的星期几 (0-6) 0 表示周日
- …
- getTime() 获取时间戳
- 时间戳: 自1970年1月1日0时0分0秒到当前时间所经历的毫秒
- Date.now() 获取当前时间戳
let d = new Date() // 直接使用new Date()创建时间对象时, 它创建的是当前的时间
// 可以在Date()构造函数中, 传递一个表示时间的字符串
// 字符串的格式: 月/日/年 时:分:秒
// d = new Date("10/20/1998 12:22:33")
// 年-月-日T时:分:秒
d = new Date("2019-12-23T12:22:33") // 格式
d = new Date()
// new Date(年份, 月, 日, 时, 分, 秒)
d = new Date(2016, 0, 1, 13, 45, 33)
result = d.getFullYear()
result = d.getMonth() + 1
result = d.getDate()
result = d.getDay()
result = d.getTime()
console.log(result)
- toLocaleDateString() 将日期转换为本地的字符串
-
toLocaleTimeString() 将时间转换为本地的字符串
-
toLocaleString()
- 将日期和时间转换为本地字符串
-
参数:
- 描述语言和国家信息的字符串
- “zh-CN” 中国 中文
- “zh-HK” 香港
- “zh-TW” 台湾
- “en-US” 英文美国
- 需要一个对象作为参数, 在对象中可以通过对象的属性来对日期的格式进行配置
- {dateStyle: “full”, timeStyle: “full”}完整的时间和日期
- dateStyle: 日期的风格
- timeStyle: 时间的等风格
- full
- long
- medium
- short
- hour12 是否采用12小时制
- true
- false
- weekday 星期的显示方式
- long 星期五
- narrow 五
- short 周五
- year 显示年份的方式
- numeric 2022 年
- 2-digit 22 年
- 描述语言和国家信息的字符串
-
const d = new Date()
let result = d.toLocaleDateString()
result = d.toLocaleTimeString()
result = d.toLocaleString("zh-CN", { year: "numeric", month: "long", day: "2-digit", weekday:"short" })
console.log(result)
11. 包装类
-
在JS中, 除了直接创建原始值外, 也可以创建原始值的对象
- 通过new String() 可以创建String类型的对象
- 通过new Number() 可以创建Number类型的对象
- 通过new Boolean() 可以创建Boolean类型的对象
- 但是千万不要这么做
-
包装类:
- 在JS中有五个包装类
- String – 字符串包装为String对象
- Number – 数值包装为Number对象
- Boolean – 布尔值包装为Boolean对象
- BigInt – 大整数包装为BigInt对象
- Symbol – 符号包装为Symbol对象
- 通过包装类可以将一个原始值包装为一个对象
- 当我们对一个原始值调用方法或属性时, JS解释器会临时将原始值包装为对应的对象
- 然后调用这个对象的属性或方法
- 由于原始值会被临时转换为对应的对象, 这就意味着对象中的方法都可以直接通过原始值来调用
- 在JS中有五个包装类
// let str = new String("hello")
// let num = new Number(11)
// let bool = new Boolean(true) // 对象比的是内存地址 它和下面不同
// let bool2 = new Boolean(true) // bool === bool2 false
// console.log(bool)
// console.log(bool2)
let str = "hello"
str.name = "哈哈哈"
console.log(str)
12. 字符串的方法
- 字符串:
- 字符串其本质就是一个字符数组
- “hwllo” – [“h”, “e”, “l”, “l”, “o”]
- 字符串的跟多方法都和数组是非常类似的
- 属性和方法:
- length 获取字符串的长度
- 字符串[索引] 获取指定位置的字符
- str.at() (实验方法)
- 根据索引获取字符, 可以接受负索引
- str.charAt() (老方法)
- 根据索引获取字符, 不可以接受负索引
- str.Concat()
- 用来链接两个或多个字符串
- str.includes()
- 用来检查字符串中是否包含某个内容
- 有返回true 没有返回false
- 用来检查字符串中是否包含某个内容
- str.indexOf()
- str.lastIndexOf()
- 查询字符串中是否包含某个内容
- 有返回第一次出现的索引, 没有就返回-1
- 查询字符串中是否包含某个内容
- str.endsWidth()
- 检查一个字符串是否以指定内容结尾
- str.starsWidth()
- 检查一个字符串是否以指定内容开头
- str.padStart()
- str.padEnd()
- 通过添加指定的内容, 使字符串保持某个长度, 第二个可以填写补充的内容
- str.repeat()
- 重复指定的代码
- str.replace()
- 使用一个新的字符串替换一个指定内容
- str.replaceAll()
- 使用一个新的字符串替换所有指定内容
- str.slice(索引, 索引) 左闭右开
- 对字符串进行切片
- str.substring()起始位置索引, 结束位置索引
- 截取字符串
- str.split()
- 用来将一个字符串拆分为一个数组
- str.toLocaleLowerCase()
- 将所有字符转换为小写
- str.toLocaleUpperCase()
- 将所有字符转换为大写
- str.trim()
- 去掉字符串前后空格
- str.trimStart()
- 去掉字符串开始空格
- str.trimEnd()
- 去掉字符串结尾空格
- length 获取字符串的长度
let str = "hello"
// console.log(str[0])
// for (char of str) {
// console.log(char)
// }
str = "hello hello how are you"
// console.log(str.includes("tom"))
// console.log(str.endsWith("you"))
str = "100"
// str = str.padStart(7, 0)
// console.log(str)
str = "hello hello how are you"
result = str.slice(12, 15)
result = str.substring(12, 15)
// result = str.replace("hello", "abc")
// result = str.replaceAll("hello", "abc")
str = "abc@bcd@nba@bfa@bpf"
result = str.split("@")
str = "abcdefg"
result = str.toLocaleLowerCase()
// result = str.toLocaleUpperCase()
console.log(result)
13. 正则表达式
- 正则表达式
- 正则表达式用来定义一个规则
- 通过这个规则计算机可以检查一个字符串是否符合规则
- 或者将字符串中符合规则的内容干提取出来
- 正则表达式也是JS中的一种对象
- 所以要使用正则表达式. 需要先创建正则表达式对象
// new RegExp()可以接收两个参数,(字符串) 1. 模式(正则表达式) 2. 标识(匹配模式)
let reg = new RegExp("a", "i") // 通过构造函数创建正则表达式对象 它可以传变量
// 使用字面量来创建正则表达式 : /正则/匹配模式
reg = /a/i
reg = /\w/
reg = new RegExp("\\w", "i")
// console.log(reg)
reg = new RegExp("a") // /a/ 表示检查字符串是否有a
// 通过正则表达式检查一个字符串是否符合规则
let str = "a"
let result = reg.test(str) // true
result = reg.test("b") // false
result = reg.test("abc") // true
result = reg.test("bcabc") // true
console.log(result)
14. 正则表达式语法
- 正则表达式中大部分字符都可以直接写
- |在正则表达式中表示或
- [ ]表示或(字符集)
- [a-z]任意的小写字母
- [A-Z]任意的大写字母
- [a-zA-Z]任意的字母
- [0-9]表示任意数字
- [a-zA-Z0-9]任意的字母和数字
- [^] 表示除了 [^x] 除了x
- . 表示换行符以外的任意字符
- 在正则表达式中使用\表示转义字符
- 其他字符集
- \w 任意的单词字符 [A-Za-z0-9_]
- \W 除了单词字符[^a-zA-Z0-9_]
- \d 任意数字[0-9]
- \D 除了数字[^0-9]
- \s 空格
- \S 除了空格
- \b 单词边界
- \D 除了单词边界
- 开头和结尾
- ^表示字符串的开头
- &表示字符串的结尾
let reg = /abc|bcd/
reg = /[a-zA-Z]/i // 匹配模式i表示忽略大小写
reg = /[^a-z]/ // 匹配包含小写字母以外内容的字符串 zH这种返回true
reg = /./
reg = /\./
reg = /^a/ // 匹配开头是a
reg = /a$/ // 匹配结尾是a才可以
reg = /^a$/ // 只匹配字母a 完全匹配, 要求字符串和正则表达式完全匹配
reg = /^abc$/
let result = reg.test("cba")
console.log(result)
15. 正则表达式
- 量词
- {m} 正好是m个
- {m,} 至少m个
- {m,n} m到n个
- + 表示一个以上, 相当于{1, }
- * 表示任意数量a
- ? 0-1次 相当于{0, 1}
let re = /a{4}/ // 最少四个a
// re = /^a{3}$/
re = /^a{3}$/ // 三个a
re = /(ab){3}/ // ababab
re = /^[a-z]{3}$/ // 三个字母
re = /^[a-z]{1,}$/ // a-z至少一个字母
re = /^[a-z]{1, 3}$/ // 一到三个字母
re = /^ba+$/
re = /^ba*$/
re = /^ba?$/
let result = re.test("baba")
console.log(result)
16. exce方法
- re.exec()
- 获取字符串中符合正则表达式的内容
let str = "abcaecafcacc"
// 提取出str符合axc格式的内容
// g表示全局匹配 需要一只调用才可以往下匹配
let re = /a([a-z])(c)/ig // []加上()可以拿到中间那个字母 ()拿到最后的内容 读取到分组中的数据
let result = re.exec(str)
// console.log(result)
while (result) {
console.log(result[0], result[1], result[2])
result = re.exec(str)
}
17. 练习
-
dajsdn13715678903jasdlakdkjg13457890657djashdjka13811678908sdadadasd
- 用自己的语言来吧规则描述, 从左往右
- 15844032580
// let re = /1[3-9]\d{9}/g
let re = /(1[3-9]\d)\d{4}(\d{4})/g
let str = "dajsdn13715678903jasdlakdkjg13457890657djashdjka13811678908sdadadasd"
let result
while(result = re.exec(str)) {
// console.log(result[0], result[1], result[2])
console.log(result[1] + "****" + result[2])
}
re = /^1[3-9]\d{9}$/ // 完整匹配只能是手机号
console.log(re.test("13456789042"))
18. 字符串正则表达式
- split()
- 可以根据正则表达式来对一个字符串进行拆分
- search()
- 可以搜索字符串符合正则表达式内容, 第一次在字符串中出现的位置
- replace()
- 根据正则表达式替换字符串中的指定内容
- match()
- 根据正则表达式匹配字符串中符合要求的内容
- matchAll()
- 根据正则表达式匹配字符串中符合要求的内容(必须设置g全局匹配)
- 它返回的是一迭代器
let str = "a@b@c@d"
let result = str.split("@")
str = "孙悟空abc猪八戒bcd沙和尚"
result = str.split(/[a-z]{3}/i)
result = str.search("abc")
str = "afgasadgasf13556671167sfasf15886080214sfsfafasfaf13944416069"
result = str.search(/1[3-9]\d{9}/)
result = str.replace(/1[3-9]\d{9}/g, "哈哈哈") // g表示全局匹配
result = str.match(/1[3-9]\d{9}/g) // 返回手机号数组
result = str.matchAll(/1[3-9]\d{9}/g) // 必须加上g
for(item of result) {
console.log(item)
}
console.log(result)
19. 垃圾回收
- 垃圾回收(Garbage Collection)
- 和生活一样, 生活时间长了会产生生活垃圾
- 程序运行一段时间后, 也会产生垃圾
- 在程序的世界中, 什么是垃圾?
- 如果一个对象没有任何一个变量对齐进行引用, 那么这对象就是一个垃圾
- 垃圾对象的存在, 会严重影响程序的性能
- 在JS中有自动的垃圾回收机制, 这些垃圾对象, 会被解释器自动回收, 我们无需手动处理
- 对于垃圾回收来说, 我们唯一能做的是就是将不在使用的变量设置为null
- 和生活一样, 生活时间长了会产生生活垃圾