这部分内容开始对JS中其他的内建对象进行补充。主要包括:结构复制、序列化、Map、Set、Date、包装类、String、正则表达式以及垃圾回收(GC)
案例:将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)
在上面的例子中,g开始有值,但是在结构后又变成undefined了,我们想要的效果是如果可以赋值就赋值,不能赋值就用原来的,这样就可以通过下面这样设置来达到效果
let [d, e, f, g] = ["唐僧", "白骨精", "蜘蛛精", "玉兔精"]
console.log(d, e, f, g)
;[d, e, f, g=g] = ["唐僧", "白骨精", "蜘蛛精"]
console.log(d, e, f, g)
解构数组时,可以使用…来设置获取多余的元素
let [n1, n2, ...n3] = [4, 5, 6, 7]
console.log(n1, n2, n3)
function fn() {
return ["二郎神", "猪八戒"]
}
let [name1, name2] = fn() // "二郎神", "猪八戒"
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]]
const arr3 = [["孙悟空", 18, "男"], ["猪八戒", 28, "男"]]
let [[name, age, gender], obj] = arr3
console.log(name, age, gender)
console.log(obj)
const obj = { name: "孙悟空", age: 18, gender: "男" }
let { name, age, gender } = obj // 声明变量同时解构对象
console.log( name, age, gender)
这个必须得在解构的时候用括号括起来,不然会将大括号解析为代码块,然后会报错
const obj = {name: "孙悟空", age: 18, gender: "男"}
let name, age, gender
;({name, age, gender} = obj)
console.log( name, age, gender)
const obj = { name: "孙悟空", age: 18, gender: "男" }
let { address } = obj
console.log(address)
const obj = { name: "孙悟空", age: 18, gender: "男" }
// 设置别名
let {name: a, age: b, gender: c} = obj
console.log(a, b, c)
const obj = { name: "孙悟空", age: 18, gender: "男" }
// 设置默认值
let {name: a, age: b, gender: c, address: d = "花果山"} = obj
console.log(a, b, c, d)
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)
,
const obj = {
"name":"孙悟空",
'age':18,
[Symbol()]:"哈哈",
[obj2]:"嘻嘻"
}
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"))
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方法一:使用方法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)
const map2 = new Map([
["name", "猪八戒"],
["age", 18],
[{}, () => {}],
])
console.log(map2)
方法一:使用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)
})
new Set()
:构造空Setnew Set([...])
:从数组构造const set = new Set()
// 向set中添加数据
set.add(10)
set.add("孙悟空")
set.add(10)
console.log(set)
size()
获取数量add()
添加元素has()
检查元素delete()
删除元素方法一: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)
})
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])
常量:
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)
Math.round(Math.random() * x)
Math.floor(Math.random() * (x + 1))
Math.round(Math.random() * (y-x) + x)
// 生成0-5之间的整数
result = Math.round(Math.random() * 5)
// 生成11-20之间的整数
result = Math.round(Math.random() * 9 + 11)
创建Date对象
let d = new Date() // 直接通过new Date()创建时间对象时,它创建的是当前的时间的对象
console.log(d)
getFullYear()
获取4位年份getMonth()
返当前日期的月份(0-11)getDate()
返回当前是几日getDay()
返回当前日期是周几(0-6) 0表示周日getHours
返回当前小时getMinutes
返回当前分钟getSeconds
返回秒getTime()
返回当前日期对象的时间戳
方法一
// 月/日/年 时:分:秒
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)
// 将日期转换为本地的字符串
console.log(d.toLocaleDateString())
// 将时间转换为本地的字符串
console.log(d.toLocaleTimeString())
// 将时间日期都转
console.log(d.toLocaleString())
toLocaleString()
可以将一个日期转换为本地时间格式的字符串
参数
描述语言和国家信息的字符串
需要一个对象作为参数,在对象中可以通过对象的属性来对日期的格式进行配置
"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 also T
)."numeric"
(e.g., 2012
)"2-digit"
(e.g., 12
)"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 also M
)."numeric"
(e.g., 1
)"2-digit"
(e.g., 01
)在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)
字符串其本质就是一个字符数组,所以字符串的很多方法都和数组是非常类似的
"hello" --> ["h", "e", "l", "l", "o"]
length
获取字符串的长度
let str = "hello"
str.length
字符串[索引] 获取指定位置的字符
let str = "hello"
str[1]
根据索引获取字符,可以接受负索引
let str = "hello"
console.log(str.at(0))
console.log(str.at(-1))
console.log(str.at(-2))
根据索引获取字符
不支持负数,传入负数返回的是空串
let str = "hello"
console.log(str.charAt(0))
用来连接两个或多个字符串
不会破坏原来的字符串,会生成新字符串
和
+
效果一样,推荐使用+
let str = "hello"
console.log(str.concat(" ", "world"))
let str = "hello hello how are you"
console.log(str.includes("hello"))
console.log(str.includes("ttt"))
console.log(str.includes("hello", 10))
查询字符串中是否包含某个内容,并返回下标,如果没有的话返回-1
第二个参数是查找的起始,不传默认为0
let str = "hello hello how are you"
检查一个字符串是否以指定内容开头或者结尾的
let str = "hello hello how are you"
通过在开头或者结尾添加指定的内容,使字符串保持某个长度
如果穿进去的第一个参数比
str.length
少,则不做任何操作
str = "100"
console.log(str.padStart(7, "0"))
console.log(str.padEnd(7, "0"))
使用一个新字符串替换一个指定内容
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
可以实现全部替换
对字符串进行切片
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)
str.split()
:用来将一个字符串拆分为一个数组
str.join()
:用来将数组拼接为字符串
str = "abc@bcd@efg@jqk"
result = str.split("@")
result = result.join("@"")
根据正则表达式拆分
将字符串转为大写或小写
str = "abcdABCD"
result = str.toLowerCase()
result = result.toUpperCase()
str.trim()
:去除字符串的前后空格str.trimStart()
:去除开始空格str.trimEnd()
:去除结束空格str = " ab c "
str.trim()
str.trimStart()
str.trimEnd()
可以去搜索符合正则表达式的内容第一次在字符串中出现的位置
str.match()
:根据正则表达式去匹配字符串中符合要求的内容str.matchAll()
:根据正则表达式去匹配字符串中符合要求的内容(必须设置g 全局匹配),返回的是一个迭代器str.match()
可以通过设置全局模式g
来匹配所有符合的字符串,并以数组的形式返回
str.matchAll()
如果不使用全局模式的话会报错,返回的是一个迭代器,使用for-of
遍历可以打印结果
通过构造函数创建: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
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
在正则表达式中大部分字符都可以直接写
| 在正则表达式中表示或(整体的或)
/abc|bcd/
表示有abc或者bcd这两个字符串[] 表示或(字符集)
[^]
表示除了
[^x]
除了x.
表示除了换行外的任意字符
在正则表达式中使用\
作为转义字符
使用括号进行分组
其他的字符集
\w 任意的单词字符,相当于 [A-Za-z0-9_]
\W 除了单词字符,相当于 [^A-Za-z0-9_]
\d 任意数字,相当于 [0-9]
\D 除了数字,相当于 [^0-9]
\s 空格
\S 除了空格
\b 单词边界
\B 除了单词边界
开头和结尾
^ 表示字符串的开头
$ 表示字符串的结尾例子
量词
+
一个以上,相当于{1,}*
任意数量的a?
0-1次,相当于{0,1}使用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)
}
re = /ab/
re.test("abc")
方法一:使用|
方法二:使用[]
垃圾回收(Garbage collection,gc)