ES6-11语法笔记
ES6新特性
let 声明变量
- 不能重复命名
- 块级作用域{}
- 不存在变量提升
- 不影响作用域链
- 里面定义的外面访问不到,外面定义的里面可以通过作用域链访问到
const 声明常量
- 必须要赋初始值(一般使用大写)
- 块级作用域{}
- 普通常量的值不能修改
- 可以对数组和对象常量中的元素进行修改
变量的解构赋值
允许按照一定模式从数组和对象中提取值,对变量进行赋值
例:
解构数组
<script>
const persons=['张三','李四','王五']
let [zg,ls,ww] =persons
console.log(zg,ls,ww);
</script>
解构对象
<script>
const zs ={
name:'张三',
age:33,
work(){
console.log('法外狂徒');
}
let {name,age,work}=zs
console.log('叫'+zs.name+' 年龄'+zs.age);
zs.work()
</script>
模板字符串 ``
- 支持换行
- 支持变量拼接
${内容}
箭头函数
<script>
// 传统方式
function fn(a,b){
return a+b
}
console.log(fn(1,2));
let fn1 = (a,b)=>{
return a+b
}
console.log(fn1(1,2));
</script>
箭头函数适用与this无关的回调,定时器,数组的方法回调
箭头函数不适用于this有关的回调,事件回调,对象的方法
this是静态的,始终指向函数声明时所在作用域下的this的值 call()方法无法改变
箭头函数不能作为构造函数new出来
不能使用argument变量 arguments是参数伪数组 在不知情多少参数的情况下使用 可以遍历
当形参有且只有一个的时候 可以省略( )
当代码体只有一条语句的时候 可以省略{ return} 语句的结果就是函数的返回值
rest参数(...args)
<script>
function fn(){
console.log(arguments);
}
// 参数对象
fn(2,3,3,3,3)
let fn1 = (a,b...args)=>{
console.log(args);
}
// 参数数组
fn1(2,4,4,4,4)
</script>
- 作用类似ES5中arguments对象保存参数,rest用数组保存参数
- rest参数必须放在参数最后
扩展运算符(将数组转变一个字符串序列)
数组的合并
<script>
const person1 = ['张三','李四']
const person2 = ['王五','赵六']
const persons = [...person1,...person2]
console.log(persons);
</script>
数组的克隆(浅拷贝)
<script>
const flower = ['薇尔莉特','伊芙加登']
const violet = [...flower]
console.log('人如其名 '+violet);
</script>
伪数组转为真数组
<script>
const divs = document.querySelectorAll('div')
// 是个对象
console.log(divs);
const newDivs =[...divs]
// 是个数组
console.log(newDivs);
</script>
Symbol的基本使用
Symbol是新的原始数据类型,表示独一无二的值,是一种类似字符串的数据类型
-
Symbol的值是唯一的,用来解决命名冲突的问题
-
Symbol的值不能用于和其他数据进行运算/对比/比较
-
Symbol定义的对象属性不能使用for...in遍历循环,但可以使用Reflect.ownKeys来获取所有对象的键名
创建独一无二的值
<script>
// Symbol 独一无二的值 创建方法
let s1 = Symbol('wkq')
let s2 = Symbol('wkq')
console.log(s1 === s2) //false
// Symbol 相同值 创建方法
let s3 = Symbol.for('wkq')
let s4 = Symbol.for('wkq')
console.log(s3 === s4) //true
避免创建对象同名的冲突
<script>
let films = {
name:'紫罗兰永恒花园',
heroine(){},
city(){},
[Symbol('heroine')]:function(){
console.log('女主角薇尔莉特.伊芙加登')
},
[Symbol('city')]:function(){
console.log('故事地点在莱顿');
}
}
console.log(films);
</script>
JavaScript七种数据类型
USONB you are so niubility 你是真牛逼
U: undefined
S: String、Symbol
O: object
N: Number、Null
B:Boolean
迭代器(自定义遍历数据)
for(let v in 迭代对象) for...in中迭代保存的是键名
for(let v of 迭代对象) for...of中迭代保存的是键值
生成器(本质就是特殊的函数 识别是函数名前加* 也是迭代器原理)
<script>
function getUsers(){
setTimeout(() => {
let data = '用户数据'
// 调用next方法,并将数据传入 这是第二个next 它的实参将作为第一个yield的返回结果
iterater.next(data)
}, 1000);
}
function getOrders(){
setTimeout(() => {
let data = '订单数据'
// 这是第三个next 它的实参将作为第二个yield的返回结果
iterater.next(data)
}, 1000);
}
function getGoods(){
setTimeout(() => {
let data = '商品数据'
// 这是第四个next 它的实参将作为第三个yield的返回结果
iterater.next(data)
}, 1000);
}
function *gen(){
let users = yield getUsers()
console.log(users);
let orders = yield getOrders()
console.log(orders);
let goods = yield getGoods()
console.log(goods);
}
// 调用生成器
let iterater = gen()
// 生成器跑起来
iterater.next()
</script>
Promise构造函数
构造函数有两个函数参数 resolve和reject 根据异步任务的执行情况改变promiseState以及promiseResult
与之对应的then函数有两个函数参数value和reason 值由promiseResult决定 状态由promiseState决定。
如果then的value和reason返回一个Promise函数 则该返回的Promise的状态和数据决定了value或reason的
状态和数据,异常的状态仍为rejected。then中可以在套Promise函数,最后以catch异常穿透,从而解决回调
地狱的问题
const fs = require('fs')
const { resolve } = require('path/posix')
const p = new Promise((resolve,reject)=>{
fs.readFile('./name.txt',(err,data)=>{
resolve(data)
})
})
p.then(v=>{
return new Promise(resolve=>{
fs.readFile('./gender.txt',(err,data)=>{
resolve([v,data])
})
})
}).then(v=>{
return new Promise(resolve=>{
fs.readFile('./age.txt',(err,data)=>{
v.push(data)
resolve(v)
})
})
}).then(v=>{
console.log(v.join(' \r\n'));
})
Set集合(本质是对象)
类似数组,但成员的值是唯一的,集合实现了迭代器接口,可以用扩展运算符和for...of进行遍历
方法
- size 返回集合元素个数
- add 增加一个元素并返回当前集合
- delete 删除元素并返回布尔值
- has 检测集合中是否包含某个元素,返回boolean值
- clear 清空集合
<script>
let s = new Set(['甘', '文', '崔', '小玉', '小玉'])
// 添加元素
s.add('阿福')
// 删除元素
s.delete('小玉')
// 长度
console.log(s.size)
// 是否存在
console.log(s.has('阿福'))
// 清空
s.clear() let nums1 = [0, 1, 2, 3, 2, 1, 0]
let nums2 = [2, 3, 4, 5, 4, 3, 2]
// 数组去重 变为集合在变为数组
let result1 = [...new Set(nums1)]
console.log(result1)
// 求交集
let result2 = [...new Set(nums1)].filter((item) =>
new Set(nums2).has(item)
)
console.log(result2)
// 求并集
let result3 = [...new Set([...nums1, ...nums2])]
console.log(result3)
// 求差集(交集的逆运算)
let result4 = [...new Set(nums1)].filter(
(item) => !(new Set(nums2).has(item))
)
console.log(result4)
</script>
Map(升级版对象 键可以多样)
键值对的集合,但是键的范围不限于字符串包括对象可以作为键,各种类型的值
集合实现了迭代器接口,可以用扩展运算符和for...of进行遍历
方法
- size 返回map的元素个数
- set 增加一个新元素并返回当前Map
- delete 删除一个元素
- get 返回键名对象的键值
- has 检测Map中是否包含某个元素,返回boolean值
- clear 清空集合并返回undefined
`
<script>
// 创建新的Map
let m = new Map()
// 添加元素
m.set('name','张三')
m.set('idea', function(){
console.log('方法可以作为值');
})
let key = {
age: 24,
}
m.set(key,[1,2,3])
// Map元素个数
console.log(m.size);
// 根据键名返回键值
console.log(m.get('idea'));
console.log(m.get(key));
// 删除一个元素
m.delete('name')
console.log(m.size);
// 是否包含某个值
console.log(m.has('idea'));
// 遍历 返回的每个元素是个数组
for(let v of m){
console.log(i);
}
// 清空Map
m.clear()
</script>
`
Class类
-
实例对象身上是没有构造函数对象身上的属性方法,构造函数对象身上的属性方法称为静态成员,有构造函数原型对象上的属性方法 构造函数.prototype.属性/方法
-
子类不能直接调用父类的同名方法,只能重写
`
<script>
class Phone {
// 构造方法 名字不能修改 在new的时候自动调用
constructor(brand, price) {
this.brand = brand
this.price = price
}
static president = '张三'
// get和set
get Info() {
console.log('信息被获取了')
// 返回值就是调用getInfo呈现的值
return '信息'
}
set Info(info) {
console.log('信息被设置了')
}
call() {
console.log('我可以打电话')
}
}
const DGD = new Phone()
console.log(DGD.president) //undefined
// 获取
console.log(DGD.Info)
// 设置
DGD.Info = '改后的信息'
// 继承
class SmartPhone extends Phone {
constructor(brand, price, color, weight) {
// super 省略了同样的this.xx=xx的编码
super(brand, price)
this.color = color
this.weight = weight
}
play() {
console.log('我能打游戏')
}
call() {
console.log('我能打视频电话')
}
}
const ET = new SmartPhone('外星人', '19999', '银色', '5kg')
ET.call()
ET.play()
</script>
`
数值扩展
-
Number.EPSILON代表JavaScript中最小精度值,如果两个浮点数相差小于该值,则为相等
-
进制数 二进制:0b开头,如0b1010 =10 八进制:0o开头,如0o777 = 511 十六进制:0x开头,如0xff = 255
-
Number.isFinite(num) 判断一个数值是否为有限数
-
Number.isNaN(num) 判断一个数值是否为NaN
-
Number.parseInt(str)和Number.parseFloat(str) 字符串转数值 夹断!! 适用于数字开头的字符串
-
Number.isInteger(num) 判断一个数值是否为整数
-
Math.trunc(float) 将数值的小数部分 夹断!!
-
Math.sign(num) 判断一个数值是正数 负数 还是0 分别返回1 -1 0
对象方法扩展
<script>
// Object.is(a,b) 判断a,b是否完全相等 a,b不为对象
console.log(Object.is(NaN, NaN))
// Object.assign(a,b) b覆盖掉a同名的属性,不存在则保留
const config1 = {
host: 'localhost',
username: 'root',
password: '123',
special: '独一份',
}
const config2 = {
host: '127.0.0.1',
username: '张三',
password: '233',
sologon: '法外狂徒',
}
console.log(Object.assign(config1, config2))
//设置原型对象 setPrototypeOf(a,b) b作为a的原型
const person ={
name:'张三',
talk:'法外狂徒'
}
const city ={
locate:'二仙桥'
}
Object.setPrototypeOf(person,city)
console.log(Object.getPrototypeOf(person));
console.log(person);
</script>
模块化 (类似乐高)将较大的程序文件拆分成多个小文件,然后将这些小文件组装
暴露模块语法汇总
// 默认暴露
export default {
name: '张三',
sologon:function() {
console.log('法外狂徒')
},
}
// 统一暴露
let age = 23
function run(){
console.log('跑得快');
}
export {age,run}
// 分别暴露
export let gender = '男'
export function jump(){
console.log('跳得远');
}
引入模块汇总
<script type="module">
// 通用引入
import * as m1 from './src/m1.js'
// 解构赋值引入(按需引入)
import {name,sologon} from './src/m1.js'
// m2.js中放在default中
import {default as m2} from './src/m2.js'
// 针对默认暴露
import m1 from './src/m1.js'
</script>
ES7新特性
Array.prototype.includes 检查数组中是否包含某个元素,返回布尔值
<script>
const books = ['张三', '李四', '王五', '赵六']
console.log(books.includes('张三')) //true
console.log(books.includes('尼古拉斯赵四')) //false
</script>
指数操作符**
<script>
let result = 2 ** 10 //** 类似Math.pow(2,10) console.log(result);
</script>
ES8新特性
async和await
1、async 函数的返回值是promise对象
promise对象的结果和状态由async函数执行的返回值决定
如果返回值是promise则由该promise的结果和状态决定
2、await右侧的表达式一般为promise对象
2.1、如果是promise对象,await返回的是promise成功的值
2.2、如果是其他,直接将此值作为await的返回值
3、await必须在async函数中 async可以没有await
如果await的promise失败了 则抛出异常 相应try...catch进行捕获
const fs = require('fs')
const util = require('util')
const mineReadFile = util.promisify(fs.readFile)
async function main(){
try {
const p1 =await mineReadFile('./content1.txt')
const p2 =await mineReadFile('./content2.txt')
const p3 =await mineReadFile('./content3.txt')
console.log(p1+p2+p3);
} catch (error) {
console.log(error);
}
}
main()
对象方法扩展
Object.keys(对象) 获取对象所有的键
Object.values(对象) 获取对象所有的值
Object.entries(对象) 获取对象所有的键值 对象转二维数组
Object.getOwnPropertyDescriptor(对象) 获取对象所有的信息
Object.create(null/{},{对象属性}) 创建带有对象属性描述的对象
ES9新特性
向对象提供rest参数和扩展运算符
<script>
function connect({host,port,...user}){
console.log(host);
console.log(port);
console.log(user); //{username: "root", password: 233}
}
connect({
host:'127.0.0.1',
port:3000,
username:'root',
password:233
})
const name={
name:'张三'
}
const sologon={
sologon:'法外狂徒'
}
const result = {...name,...sologon}
console.log(result); //{name: "张三", sologon: "法外狂徒"}
</script>
正则扩展
命名捕获分组
<script>
// 会多一个groups里面是url和text 这样方便提取捕获 ?<别名>
let str = '<a href="https://www.baidu.com">百度</a>'
const reg = /<a href=(?<url>.*)>(?<text>.*)<\/a>/
const result = reg.exec(str)
console.log(result)
console.log(result.groups.url) //"https://www.baidu.com"
console.log(result.groups.text) //百度
</script>
断言
<script>
// 通过前面和后面 判断唯一性
let str1 = '心野2222啦啦'
// 正向断言 通过后面 判断前面的是否匹配
const reg1 = /\d+(?=啦)/
// 反向断言 通过前面 判断后面的是否满足
const reg2 =/(?<=啦)\d+/
const result1 = reg1.exec(str1)
const result2 = reg2.exec(str1)
console.log(result1);cd
console.log(result2);
</script>
dotAll模式(简略换行)
<script>
let str = `
<ul>
<li>
<a>肖申克的救赎</a>
<p>上映日期:1994-09-10</p>
</li>
</ul>`
// 之前
const reg1 =/<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/
const result1 = reg1.exec(str)
console.log(result1);
// dotAll模式 .*? 替代 /s 同时在正则后加s
const reg2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/s
const result2 = reg2.exec(str)
console.log(result2);
</script>
E10新特性
对象方法扩展
Object.fromEntries 获取数组所有的键值 二维数组转对象
<script>
const result = Object.fromEntries([
['name', '张三'],
['sologon', '法外狂徒'],
])
console.log(result)
const result1 = Object.entries({
name: '张三',
sologon: '法外狂徒',
})
console.log(result1);
const m = new Map()
m.set('name','张三')
m.set('sologon','法外狂徒')
console.log(m);
</script>
字符串方法扩展
trimStart和trimEnd清除左右空白
<script>
let str = ' 还有一件事 要用魔法打败魔法 '
console.log(str)
console.log(str.trim())
console.log(str.trimStart())
console.log(str.trimEnd())
</script>
数组方法扩展
flat 降低数组维度 和 flatMap 先map函数处理返回如果是多维再flat降低维度
<script>
//flat(数字) 降低维度 数字从0开始 0默认为一维 降到多少维写多少
let arr = [1, 2, 3, [4, 5, 6, [7, 8, 9]]]
let result1 = arr.flat(2)
console.log(arr) //(4) [1, 2, 3, Array(4)]
console.log(result1) //[1, 2, 3, 4, 5, 6, 7, 8, 9]
//flatMap 先map再flat
let arr1 = [1, 2, 3, 4]
let result2 = arr.map((item) => [item * 10]) //返回形式如果多维 要降维度
let result3 = arr.flatMap((item) => [item * 10])
console.log(result2)
console.log(result3)
</script>
Symbol扩展
symbol.prototype.description Symbol的描述
<script>
let s = Symbol('我是Symbol的描述')
console.log(s.description);
</script>
E11新特性
私有属性 #属性
<script>
class Person {
// 公有属性可以在外部获取
name
// 私有属性 只可以由内部方法获取
#age
#weight
constructor(name, age, weight) {
this.name = name
this.#age = age
this.#weight = weight
}
getAtrribute() {
console.log(this.name)
console.log(this.#age)
console.log(this.#weight)
}
}
let zs = new Person('张三', 23, 100)
console.log(zs.name)
console.log(zs.age) //私有属性 是undefined
zs.getAtrribute() //私有属性通过方法 this.#xx获取
</script>
Promise扩展
Promise.allSettled
接收promise数组 返回结果是promise 成功的状态 值是数组中各个promise的状态和数据
<script>
const p1 = new Promise((resolve, reject) => {
resolve('成功!')
})
const p2 = new Promise((resolve, reject) => {
try {
// reject('失败!')
throw '出错啦'
} catch (error) {
console.warn(error);
}
})
const pArr = [p1, p2]
let result = Promise.allSettled(pArr)
console.log(result)
let result1 = Promise.all(pArr)
console.log(result1);
</script>
字符串扩展
String.prototype.matchAll(正则表达式) 用于得到正则批量匹配的结果 用于正则匹配提取数据
<script>
let str = `
<ul>
<li>
<a>肖申克的救赎</a>
<p>上映日期:1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1994-07-06</p>
</li>
</ul>`
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
const result =str.matchAll(reg)
for(v of result){
console.log(v);
}
console.log(...result);
</script>
可选链操作符
当所属值在对象的深处,省去层层判断
<script>
function main(config){
// 传统方案
// const dbPassWord = config && config.db && config.db.password
// 可选链操作符 x?.y 如果x有,在去传入y
const dbPassWord = config?.config.db?.db.password
console.log(dbPassWord);
}
main({
db:{
name:'MySql',
password:222
},
cache:{
name:'高速缓存区',
password:333
}
})
</script>
动态导入
import(路径)返回的是promise对象 可以用then 实现promise成功的数据
<body>
<button id="btn">点击获取方法</button>
<script>
const btn = document.querySelector('#btn')
btn.onclick =function(){
import('./src/m1.js').then(module=>{
console.log(module.sologon());
})
}
</script>
</body>
大整型数据类型
用于大数值的计算
<script>
let n = 1024n //整数n 即表示是个大整型数据
let max = Number.MAX_SAFE_INTEGER //最大安全整数
console.log(max + 1)
console.log(max + 2)
console.log(BigInt(max) + BinInt(1))
console.log(BigInt(max) + BinInt(2))
</script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!