数组函数的处理
let arr = [3,5,7,9,10]
//find返回第一个满足条件的元素 没有则为 undifine
const find = arr.find((v)=>{
return v > 11
})
console.log(find)
//findIndex 返回第一个满足元素的下标 没有则为 -1
const findIndex = arr.findIndex((v)=>{
return v > 3
})
console.log(findIndex)
//every全部都满足条件则为true否则为false
const every = arr.every((v)=>{
return v > 3
})
console.log(every)
//some数组中有一个条件满足就为true 否则为false
const some = arr.some((v)=>{
return v > 3
})
console.log(some)
1.let说明
//1.变量不能重复申明
let star = '123'
let star = '123'
//2.块级作用域 全局,函数,eval
//if else while for
{
let girl = '女孩'
}
console.log(girl)//找不到girl 会报错
//3.不存在变量提升
console.log(song)//下面 let会报错 val声明为undifine
let song = '恋爱达人'
//4.不影响作用域链
{
let school = '学校'
function fn(){
console.log(school)//学校 会找父级
}
fn()
}
2.const常量声明
1.常量声明一定要赋初始值
2.一般常量使用大写
3.常量不能修改
4.块级作用域
5.对于数组和对象的元素修改,不算做常量的修改,不会报错
3.解构赋值
1.数组解构
let [a,b] = [1,2]
2.对象解构
let {a,b} = {a:1,b:2}
4.模板字符串
let start = 200
let a = `这是一个模板字符串${start}`
5.简写对象
let name = '张三'
let age = '18'
//简写
let obj = {
name,
age,
get (){
console.log('这是es6简写方法')
}
}
6.箭头函数
//1.this是静态的,this始终指向函数声明时所在作用域下的this的值 call和aplly
//2.不能作为构造函数实例化对象
let person = (name) =>{
this.name = name
this.age = age
}
let me = new Person('张')
console.log(me)//会报错
//3.不能使用arguments
let fn = ()=>{
console.log(arguments)//不能使用
}
fn(1,2,3)
//4.箭头函数简写
//(1)省略小括号
//(2)省略花括号(此时return也必须省略)
应用场景
(1) 箭头函数适合与this无关的回调,定时器,数组的方法回调
(2) 箭头函数不适合与this有关的回调,事件回调,对象方法
7.给函数参数赋初始值
//1.形参初始值,具有默认值的参数1.形参初始值,具有默认值的参数,一般位置靠后
function (a,b,c=10){
return a+b+c
}
console.log(add(1,2))//13
//2.与解构赋值结合
let params = {
name:'张三',
age:'18'
}
get(params)
function get({name='李四',age}){
console.log(name,age)
}
8.rest参数
//1.ES6引入rest参数,用于获取函数的实参,用来代替argument
function fn(...args){
console.log(args)//['阿','柏','思']
}
fn('阿','柏','思')
//2.rest参数 ...args 必须放在参数最后
fn(a,b,...args)
9.扩展运算符 ...
1.数组的合并
let a = [1,2]
let b = [5,6]
let c = [...a,...b]//[1,2,5,6]
//2.数组的克隆
const a = [1,2]
const b = [...a]//[1,2]
//3.将伪数组转为真正的数组
eg: arguments的数组类型
10.Symbol
1.创建Symbol
let s = Symbol()
let s2 = Symbol('少硅谷')
let s3 = Symbol('少硅谷')
s2 !== s3
//Smybol.for 创建
let s5 = Symbol.for('少硅谷')
//2.不能与其他数据进行运算
let rel = s + 100//会报错
11.迭代器
eg:Array的迭代器
const xiyou = ["🐖","猴","🐎",'唐僧']
let iterator = xiyou[Symbol.iterator]()
//done为true表示执行完毕
console.log(iterator.next())//{value: "🐖", done: false}
console.log(iterator.next())//{value: "猴", done: false}
console.log(iterator.next())//{value: "🐎", done: false}
console.log(iterator.next())//{value: "唐僧", done: false}
console.log(iterator.next())//{value: undefined, done: true}
案例说明:将对象可以使用 for of遍历
//这样遍历会报错 In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
//[Symbol.iterator]() 对象里面必须要有这个迭代器
let obj = {
name:'张三',
stus:['张','望','月']
}
for (const v of obj) {
console.log(v)
}
//正确的for of遍历对象里面的数组
let obj = {
name:'张三',
stus:['张','望','月'],
//添加一个迭代器
[Symbol.iterator]() {
let index = 0
return {
next:()=>{
if(index < this.stus.length){
const result = {value:this.stus[index],done:false}
index ++
return result
}else{
return {value:undefined,done:true}
}
}
}
}
}
for (const v of obj) {
console.log(v)//'张','望','月'
}
12.生成器
//生成器其实就是一个特殊的函数
//异步编程 纯回调函数 node fs ajax mongodb
//yield 为函数代码的分隔符 通过调用 next()方法 一步一步执行
function * gen(){
console.log(111)
yield '操作2'
console.log(222)
yield '操作3'
console.log(333)
}
let iterator = gen()
// iterator.next()//111
// iterator.next()//222
// iterator.next()//333
for (const v of iterator) {
console.log(v)
}
生成器函数参数
//1.整体传参 在gen函数括号里传
//2.next函数传参 yield '操作2'返回的结果是参数
function * gen(arg){
console.log(arg)//整体参数
const one = yield '操作2'
console.log(one)//next参数1
const two = yield '操作3'
console.log(two)//next参数2
}
let iterator = gen('整体参数')
iterator.next()
iterator.next('next参数1')
iterator.next('next参数2')
生成器函数实现异步
(1) 案例1
//需求 1s打印 111 2s打印222 3秒打印333
function one (){
setTimeout(()=>{
console.log(111)
iterater.next()
},1000)
}
function two (){
setTimeout(()=>{
console.log(222)
iterater.next()
},2000)
}
function three (){
setTimeout(()=>{
console.log(333)
iterater.next()
},3000)
}
function * gen(){
yield one()
yield two()
yield three()
}
let iterater = gen()
iterater.next()
(2) 案例2
//模拟按顺序获取 用户数据 订单数据 商品数据
function getUser(){
setTimeout(()=>{
let data = '用户数据'
iterator.next(data)
},1000)
}
function getOrder(){
setTimeout(()=>{
let data = '订单数据'
iterator.next(data)
},1000)
}
function getPro(){
setTimeout(()=>{
let data = '商品数据'
iterator.next(data)
},1000)
}
function * gen(){
let user = yield getUser()
let order = yield getOrder()
let pro = yield getPro()
console.log(user)
console.log(order)
console.log(pro)
}
let iterator = gen()
iterator.next()
13.Promise
//实例化Promise对像
let promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
// let data = '数据库中的用户数据'
// resolve(data)//成功时调用
let data = '数据读取失败'
reject(data)//失败时调用
},1000)
})
promise.then((value)=>{
//成功时执行
console.log(value)
},(err)=>{
//失败时执行
console.error(err)
})
- Promise封装读取文件
const fs = require('fs')
let p = new Promise((resolve,reject)=>{
fs.readFile('./file.md1',(err,data)=>{
if(err) reject(err)
resolve(data)
})
})
p.then((value)=>{
console.log(value.toString())
},(err)=>{
console.log('读取文件失败')
})
- Promise封装请求
const p = new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest()
xhr.open('GET','/static/data.json')
xhr.send()
xhr.onreadystatechange = function (){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
//请求成功
resolve(xhr.response)
}else{
//请求失败
reject(xhr.status)
}
}
}
})
p.then((value)=>{
console.log(value)
},(err)=>{
console.log(err)
})
- then方法说明
1. 调用then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定(成功:resolved, 失败:reject)
2.如果回调函数中返回的结果是 非promise类型的属性,则状态为成功,返回值为对象的成功值
3.因为.then方法返回的是promise对象 所以可以链式调用
- then方法的链式调用
const fs = require('fs')
const p = new Promise((resolve,reject)=>{
fs.readFile('../static/古诗.md',(err,data)=>{
resolve(data)
})
})
p.then((value)=>{
return new Promise((resolve,reject)=>{
fs.readFile('../static/开心.md',(err,data)=>{
resolve([value,data])
})
})
}).then((value)=>{
console.log(value.toString())
})
- catch方法
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
let data = '数据读取失败'
reject(data)//失败时调用
},1000)
})
p.catch((err)=>{
console.log(err)//reject时执行
})
14.集合Set
//集合
const s = new Set()
const s2 = new Set([1,2,3,1,2])
console.log(s2)//[1,2,3] 会自动去重
//添加元素
s2.add(5)
console.log(s2)//[1,2,3,5]
//删除元素
s2.delete(1)
console.log(s2)//[2,3,5]
//检测元素
console.log(s2.has(3))//true
//清空
s2.clear();
console.log(s2)
案例
let arr = [1,2,3,4,5,1,2,3]
let arr2 = [4,5,6,5,6]
//去重
let rel = [...new Set(arr)]
console.log(rel)//[1,2,3,4,5]
//求交集
let rel = [...new Set(arr)].filter(v=> new Set(arr2).has(v))
console.log(rel)//[4,5]
//求并集
let rel = [...new Set(arr),...new Set(arr2)]
console.log(rel)//[1,2,3,4,5,6]
//求差集 (arr里面有,arr2里面没有)
let rel = [...new Set(arr)].filter(v=>!(new Set(arr2).has(v)))
console.log(rel)//[1,2,3]
//有iterator接口 可以用for of遍历
for (const v of rel) {
console.log(v)
}
15.Map(升级版的对象)
//声明
let m = new Map()
//添加元素
m.set('name','尚硅谷')
m.set('change',()=>{
console.log('我们可以改变世界')
})
//以对象作为key
let key = {
school:'长江大学'
}
m.set(key,['静静','菁菁','婧婧'])
//长度
console.log(m.size)
//删除
m.delete('name')
//获取
console.log(m.get('change'))
console.log(m.get(key))
16.class类
class Phone {
constructor (brand,price){
this.brand = brand
this.price = price
}
call(){
console.log('我可以打电话')
}
}
let onPlus = new Phone('+1',5999)
console.log(onPlus)
- 静态属性 static
//static 申明的属性属于类 不属于类的实例对象
class Phone {
static name = '张三'
static change (){
console.log('我时谁')
}
}
let nike = new Phone()
console.log(Phone.name)//张三
console.log(nike.name)//undifine
- 类的继承
extends
class Phone {
constructor (brand,price){
this.brand = brand
this.price = price
}
call (){
console.log('我可以打电话')
}
}
class smartPhone extends Phone {
constructor (brand,price,color,size){
super(brand,price)//类似es5的Phone.call(this,brand,price)
this.color = color
this.size = size
}
photo (){
console.log('拍照')
}
playGame (){
console.log('玩游戏')
}
//子类声明和父类一样的方法 是对父类方法的重写
call (){
console.log('我可以重写父类的call')
}
}
let xiaomi = new smartPhone('小米','1999','红色','5.1incu')
console.log(xiaomi)
xiaomi.call()
xiaomi.photo()
xiaomi.playGame()
get和set
class Phone {
get price (){
console.log('张三')
}
set price (newVal){
console.log(newVal)
}
}
let p = new Phone()
console.log(p.price)//张三
p.price = 'free'//free
17.数值扩展
//过滤掉数字后面的文字
console.log(Number.parseInt('123神器'))//123
console.log(Number.parseFloat('3.1415926神器'))
//判断是否为整数
console.log(Number.isInteger(2.5))//false
//将数字的小数部分抹掉
console.log(Math.trunc(3.5))
18.对象方法扩展
//Object.is 判断两个值是否完全相等
console.log(Object.is(120,120))//true
console.log(Object.is(NaN,NaN))//true Object.is可以判断NAN 而 === 不可以
console.log(NaN === NaN)//false
//Object.assign 对象的合并
const obj1 = {
name:'张撒谎',
age:'13',
test:'90'
}
const obj2 = {
name:'皇上',
age:'18'
}
console.log(Object.assign(obj1,obj2))//{name:'皇上',age:'18',test:'90'}
19.ES7新特性
includes
const arr = ['张','王','李']
console.log(arr.includes('张'))//true
console.log(arr.includes('招'))//false
- **
//2的10次方
console.log(2 ** 10)//1024
console.log(Math.pow(2,10))
20.ES8新特性
async和await
async
//async返回的是一个promise实例
async function fn(){
return 123
}
const rel = fn()
console.log(rel)
rel.then((value)=>{
console.log(value)
},(err)=>{
console.log(err)
})
await
const p = new Promise((resolve,reject)=>{
//let data = '测试数据'
//resolve(data)
reject('错误了吗?')
})
async function main (){
try {
const rel = await p
console.log(rel)
} catch (err) {
console.error(err)
}
}
main()
21.ES8的对象方法的扩展
const obj = {
name:'zhangsan',
sonObj:{
name:'zhang',
ege:12
},
sonArr:[1,2,3]
}
//获取对象所有的Key
console.log(Object.keys(obj))//["name", "sonObj", "sonArr"]
//获取对象所有的value值
console.log(Object.values(obj))//["zhangsan", {…}, Array(3)]
//获取键和值打印结果如下
// 0: (2) ["name", "zhangsan"]
// 1: (2) ["sonObj", {…}]
// 2: (2) ["sonArr", Array(3)]
console.log(Object.entries(obj))
//entries 可以将对像转成map
const m = new Map(Object.entries(obj))
console.log(m)//Map(3) {"name" => "zhangsan", "sonObj" => {…}, "sonArr" => Array(3)}
console.log(m.get('sonObj'))//{name: "zhang", ege: 12}
//获取对象属性的描述对象 可用于深层次拷贝
console.log(Object.getOwnPropertyDescriptor(obj))
22.ES9正则扩展 命名捕获分组
const str = '<a href="http://www.baidu.com">百度</a>'
const reg = /<a href="(?<url>.*)">(?<test>.*)<\/a>/
const result = reg.exec(str)
console.log(result.groups.url)//http://www.baidu.com
console.log(result.groups.test)//百度
23.正则反向断言
const str = 'j123456大苏打默默555哒哒哒'
//正向断言获取str中 555 字符
const reg = /\d+(?=哒)/
const result = reg.exec(str)
//反向断言获取str中 555 字符
const reg2 = /(?<=默)\d+/
const result2 = reg2.exec(str)
console.log(result2)
24.正则dotAll模式获取li所有内容
25.对象的扩展方法 fromEntries
//将二维数组转成键值对象和entries相反
const rel = Object.fromEntries([
['name','张三'],
['xuexi','js,css,node']
])
console.log(rel)//{name: "张三", xuexi: "js,css,node"}
//Map 装成键值对象
const m = new Map()
m.set('name','张三')
console.log(Object.fromEntries(m))//{name: "张三"}
26.清除字符串空白
const str = ' 哈哈哈 '
console.log(str)
console.log(str.trimStart())//清除左侧空白字符
console.log(str.trimEnd())//清除右侧空白字符
27.将二维数组转成一维数组
私有属性
class Person {
//公有属性
name;
//私有属性 加 #
#age;
#weight;
constructor(name,age,weight){
this.name = name
this.#age = age
this.#weight = weight
}
intro (){
console.log(this.name)
console.log(this.#age)//18 类里面可以访问
console.log(this.#weight)//110 类里面可以访问
}
}
const girl = new Person('小妹','18','110')
//console.log(girl.name)
//console.log(girl.#age)//类里面的私有变量外部不能访问 报错
//console.log(girl.#weight)//类里面的私有变量外部不能访问 报错
girl.intro()
28.matchAll方法
29.可选链操作符 ?.
获取对象里面某个属性时可代替判断对象是否存在
function main (config){
//获取 config里面的host属性 要判断 因为不传会报错
//普通获取
//const host = config && config.db && config.db.host
//使用 ?. 获取
const host = config?.db?.host
console.log(host)
}
main({
db:{
host:'192.168.41.105',
name:'开发'
},
catch:{
host:'192.168.41.74',
name:'测试'
}
})
30.动态导入
31.globalThis
不管是浏览器还是node环境 始终指向全局对象 可直接使用
浏览器指向 window对象
node环境 指向globle