ES6的版本变动内容最多,具有里程碑意义
ES6加入了很多新的语法特性,编程更简单高效
ES6是前端发展趋势,就业必备技能
Vue前置课程 ES6-ES11
2015年 ES6 每年一个版本,2022年最新的版本是ES13
ECMA-262 版本列表
https://www.ecma-international.org/publications-and-standards/standards/ecma-262/
为什么学习ES6
ES6的版本变动内容最多,具有里程碑意义
ES6加入了很多新的语法特性,编程更简单高效
ES6是前端发展趋势,就业必备技能
第1章 ESMAScript6新特性
Let
1、赋值
let a;
let b,c,d;
let e=100;
let f=521,g="iloveyou",h=[];
不允许重复声明同一个变量。
2、块级作用域 (全局,函数,eval(ES5的严格模式)
只在代码块{}中有效, if else while for 对应的{}都是块级作用域
3、不存在变量提升
4、不影响作用域链
<script>
let items=document.getElementsByTagName("div")
for(var i=0 ;i<items.length;i++){
items[i].onclick=function(){
//this.style.background="pink"
console.log(i);
items[i].style.background="pink"
}
}
</script>
3
let.html:28 Uncaught TypeError: Cannot read properties of undefined (reading 'style')
at items.<computed>.onclick (let.html:28:26)
i 用var声明会报错, 因为var声明的是全局变量,循环结束后i已经变成了3,item[3]是不存在的
改成let 就Ok了
const
- 声明常量一定要赋初始值
- /一般常量使用大写
- /常量的值不能修改
- /块级作用域
- /对于数据和对象的元素修改,不算对常量的修改,不会报错
const COMPANY ="aobo"
变量解构赋值
<script>
const F4=['小沈阳','刘能','赵四','宋小宝']
let [xiao,liu,zhao,song] = F4
console.log(xiao)
console.log(liu)
console.log(zhao)
console.log(song)
const zhaobenshan={
name:"赵本山",
age:55,
xiaopin:function(){
console.log("我可以演小品")
}
}
// let {name,age,xiaopin} = zhaobenshan;
// console.log(name);
// console.log(age);
// console.log(xiaopin);
let {xiaopin} = zhaobenshan;
xiaopin();
</script>
模板字符串
·· 一对反引号来包括
- 内容可以有换行符
- 支持变量拼接,用${}包含变量
let area='山东'
let str=`我是${area}
的`;
// 内容可以有换行符
// 变量拼接
console.log(str);
对象的简洁写法:
let name="fatux";
let fn = function(){
console.log(name);
}
const me={
name,
fn,
improve(){
console.log("活到老,学到老")
}
}
//等价于:
const me2={
"name":name,
"fn":fn,
"improve":function(){
console.log("活到老,学到老")
}
}
箭头函数
let fn=(a,b)=>{
return a+b;
}
console.log(fn(1,2));
// 跟之前的匿名函数有什么区别呢?
//1 this是静态的,this始终指向函数声明时所在作用域下的this的值(外层的this值)
// 这句话要分两步来说明:
// 1 定义函数的作用域, 我们知道{}定义作用域, 所以下面的getName2的作用域其实是全局的window,
// 2 那箭头函数中指向的this,也就是定义它的作用域window,this.name也就是window.name
// 箭头函数和普通函数的区别就是this指向不同.
function getName(){
console.log(this.name);
}
let getName2=()=>{
console.log(this.name);
}
window.name="lisi"
const p={
name:"zhansan"
}
getName.call(p)
getName2.call(p)
// 2不能作为构造函数实例化对象
// 3 不能使用arguments变量
// 4 简写方法
// 省略小括号 ,当形参有且只有一个
let add= n=>{
return n++;
}
// 省略花括号,当代码体只有一条,return 也要省略
let pow=(n) => n*n;
let power=n =>n*n;
案例:
过滤数组:
let arr=[1,2,4,5,77,88];
let result=arr.filter(item=>item % 2 ===0);
console.log(result);
注意:
- 箭头函数适合与this无关的问题,定时器,数组的方法等。
- 不适合与this有关的问题, 事件问题,对象方法。
- 箭头函数就是代表一段逻辑
ES6函数形参的初始值
这他么的是跟python学的
// 具有默认值的参数,一般位置要靠后
function add(a,b,c=10){
return a+b+c;
}
let result=add(1,2);
console.log(result);
// 可以与结构赋值结合
function connect({host="127.0.0.1",username,password,port=3306}){
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
username:"fatux",
password:"fatux",
})
rest参数
ES6引入了rest参数,用于获取函数的实参,来代替arguments
// function date(){
// console.log(arguments);
// }
// date(1,2,3);
function date(...args) {
console.log(args);
}
date(1,2,3,4)
// 返回一个数组
// rest参数必须放在最后
ES6扩展运算符
//扩展运算符能将数组转换为逗号分隔的【参数序列】
//声明一个数组...
const tfboys = ['1','2','3']
function count(){
console.log(arguments);
}
// 声明一个函数
count(...tfboys);
// 1.数组的合并
const kuaizi=['王太利','肖阳'];
const fenghuang =['曾毅','玲花']
const zuixuanxiaopingguo = kuaizi.concat(fenghuang)
console.log(zuixuanxiaopingguo);
const zuixuanxiaopingguo2 =[...kuaizi,...fenghuang]
console.log(zuixuanxiaopingguo2);
//2、数组的克隆,如果数组内部元素有引用类型,也是浅拷贝
const sanzhihua =["E",'G',"M"];
const sanyecao = [...sanzhihua]
//3、将伪数组转成真正的数组
const divs=document.querySelectorAll('div');
const divArr=[...divs];
console.log(divArr);
symbol
说实话,我没看懂…
js的第七种数据类型,是一种类似字符串的数据类型
symbol特点:
- symbol的值是唯一的,用来解决命名冲突问题
- symbol的值不能与其他数据进行运算
- symbol定义的对象属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象所有的健名
let s=Symbol();
console.log(s);
let s2=Symbol("fatux");
let s3=Symbol("fatux");
console.log(s2===s3);
//返回false
let s4=Symbol.for("fatux");
let s5=Symbol.for("fatux");
console.log(s4===s5);
//返回true
//向对象添加方法 up,down
let game={
}
let methods={
up:Symbol(),
down:Symbol()
}
game[methods.up] = function(){
console.log("我可以改变形状");
}
game[methods.down]=function(){
console.log("我可以快速下降");
}
console.log(game);
let youxi={
name:"狼人杀",
[Symbol("say")]:function(){
console.log("我可以发言");
},
[Symbol("zibao")]:function(){
console.log("我可以自爆");
},
}
console.log(youxi);
Symbol的内置值
// 内置属性
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用来监测类型了");
return true;
}
}
let o={};
console.log(o instanceof Person);
const arr=[1,2,3];
const arr2=[4,5,6];
arr2[Symbol.isConcatSpreadable]=false;
console.log(arr.concat(arr2));
特定场景下自动调用,扩展对象功能。
迭代器
1、迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作
2、原生具备iterator接口的数据(可以用for of遍历)
Array Arguments Set Map String TypedArray NodeList
3、工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直向后移动,直到指向最后一个成员
- 每调用next方法返回一个包含value和done属性的对象
注意: 需要自定义遍历数据的时候,要想到迭代器
const xiyou=['唐僧','孙悟空','猪八戒']
for(let v of xiyou){
console.log(v);
}
let iterator = xiyou[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
迭代器的应用-自定义遍历数据
const banji={
name: "终极一班",
stus:[
"xiaoming",
"xiaoning",
"xiaotian",
"knight"
],
[Symbol.iterator](){
let index=0;
let _this = this;
return{
next: function(){
if (index< _this.stus.length){
const result = {
value:_this.stus[index],
done:false
}
index++;
return result;
} else{
return {value:undefined,done:true}
}
}
}
}
}
for(let v of banji){
console.log(v);
}
生成器
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
// 生成器其实就是一个特殊的函数
// 异步编程,纯回调函数 node fs ajax mongodb
function * gen(){
console.log(111);
yield 'code1'
console.log(222);
yield 'code2'
console.log(333);
yield 'code3'
console.log(444);
yield 'code4'
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
for(let v of gen()){
console.log(v);
}
生成器函数怎么做对异步编程产生影响呢?
跟io有关的都可以用异步操作
// 回调地狱
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 3000);
}, 2000);
}, 1000);
// 生成器实例
function one() {
setTimeout(() => {
console.log(111);
iterator.next();
}, 1000);
}
function two() {
setTimeout(() => {
console.log(222);
iterator.next();
}, 2000);
}
function three() {
setTimeout(() => {
console.log(333);
iterator.next();
}, 3000);
}
function* gen() {
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next();
function getUsers() {
setTimeout(() => {
let data="用户数据";
iterator.next(data);
}, 1000);
}
function getOrders() {
setTimeout(() => {
let data="订单数据";
iterator.next(data);
}, 2000);
}
function getGoods() {
setTimeout(() => {
let data="商品数据";
iterator.next(data);
}, 3000);
}
function* gen() {
let users = yield getUsers();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
let iterator = gen();
iterator.next();
总结: 关键在于next方法,将异步的方法做成感觉像同步的 。 以前是用回调函数,用生成器貌似优雅一些。
本质上是编程思想的进化。
Promise
promise是ES6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取成功或失败的结果。
// new Promise 生成一个异步任务,参数是具体执行任务的函数,接收两个参数
// 一般叫resolve和reject都是函数,异步任务执行成功调用前者,否则调用后者
// 这两个方法将改变p对象的状态,同时给下一步处理传递数据
// 然后调用p.then ,接收两个函数型参数,分别对应异步任务成功的回调和失败的回调
const p = new Promise(function(resolve,reject){
setTimeout(function () {
// let data="数据库中的用户数据";
// resolve(data);
let err="数据读取失败";
reject(err);
},1000);
})
p.then(function(value){
console.log(value);
},function(reason){
console.error(reason);
})
// 其实promise解决的也是回调地狱,嵌套过多的问题,将异步任务封装成对象了
Promise读取文件
需要安装nodejs
<script>
const fs = require('fs');
const p = new Promise(function(resolve,reject){
fs.readFile('./abc.txt',(err,data)=>{
if(err) reject(err);
resolve(data);
})
})
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log(reason);
})
</script>
Promise链式调用
promise then可以返回一个promise,可以形成链式调用。
下面的代码需要nodejs支持(未测试)
const fs = require('fs');
const p = new Promise(function(resolve,reject){
fs.readFile('./abc.txt',(err,data)=>{
resolve(data);
})
})
p.then(function(value){
return new Promise((resolve,reject)={
fs.readFile('./abcd.txt',(err,data)=>{
resolve([value,data]);
})
});
}).then(value=>{
return new Promise((resolve,reject)=>{
fs.readFile("./abcde.txt",(err,data)={
value.push(data);
})
})
}).then(value =>{
console.log(value);
})
promise的catch方法
类似语法糖,可以只接收一个回调,就是then中失败的回调。
Set
集合,类似于数组,不过成员值是唯一的,集合实现了iterator接口。 所以可以使用扩展运算符合for。。。of进行遍历,集合的属性和方法:
size 返回集合的元素个数
add 增加一个新元素,返回当前集合
delete 删除元素,返回boolean值
has 检测集合中是否包含某个元素,返回boolean值
集合里的元素只能是字符串???
const s=new Set();
const s2=new Set([1,2,3,4,4]);
const s3=new Set(["大事","小事","好事"]);
console.log(s2);
console.log(s3);
// 集合会自动去重
console.log(s2.size);
for(let v of s2){
console.log(v);
}
s2.add(5);
console.log(s2);
s2.delete(4);
console.log(s2);
console.log(s2.has(5));
s2.clear();
console.log(s2);
集合实践
1、数组去重
const arr= [1,2,3,4,5,6,2,3,4,4];
let result = [...new Set(arr)]
console.log(result);
2、求交集
let arr= [1,2,3,4,5,6,2,3,4,4];
let arr2 = [4,5,6,5,4];
let result = [...new Set(arr)].filter(item=>new Set(arr2).has(item))
console.log(result);
3、求并集
let arr= [1,2,3,4,5,6,2,3,4,4];
let arr2 = [4,5,6,5,4,7,8];
let result = [...new Set([...arr,...arr2])]
console.log(result);
4、差集
概念:A,B两个集合,A对B的差集,指在A里有,但是在B里没有的数据,刚好是交集的逆运算
let arr= [1,2,3,4,5,6,2,3,4,4];
let arr2 = [4,5,6,5,4];
let result = [...new Set(arr)].filter(item=>!(new Set(arr2).has(item)))
console.log(result);
Map
ES6提供了Map数据结构,它类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象) 都可以当做键。 map也实现了iterator接口,所以可以用扩展运算符和for…of遍历。map的属性和方法:
size 返回元素的个数
set 增加一个新元素,返回当前map
get 返回键名对象的键值
has 监测Map中是否包含某个元素,返回boolean值
clear 清空集合,返回undefined
let m=new Map();
m.set('name','fatux');
console.log(m);
m.set('change',function(){
console.log("我们可以改变你");
})
console.log(m.get("change"));
console.log(m.size);
for (let v of m){
console.log(v);
}
class
ES6提供了更接近传统语言的写法,引入了class(类)这个概念,作为对象的模板。 通过class关键字,可以定义类。 基本上ES6的calss可以看作只是一个语法糖,他的绝大部分功能,ES5都能做到,新的class写法只是让对象原型的写法更清晰,更像面向对象编程的语法而已。
知识点:
- class 声明类
- constructor 定义构造函数初始化
- extends 继承父类
- super调用父级构造方法
- static 定义静态方法和属性
- 父类方法可以重写
// ES5的写法
// function Phone (brand,price){
// this.brand = brand;
// this.price=price;
// }
// Phone.prototype.call = function(){
// console.log("我可以打电话");
// }
// let huawei=new Phone('华为',5999)
// huawei.call()
// console.log(huawei);
//ES6的写法
class Phone{
constructor(brand,price){
this.brand = brand;
this.price=price;
}
call(){
console.log("我可以打电话");
}
}
let huawei=new Phone('华为',5999)
huawei.call()
console.log(huawei);
静态成员
ES5中: 函数对象和实例对象是两回事,实例对象只有函数原型中的属性和方法。
函数的对象和方法被称为静态成员
在class中用static关键字 指定静态成员,只属于类,而不属于实例对象。
class Phone{
static name="手机";
static change(){
console.log('我可以改变世界');
}
}
let nokia=new Phone();
console.log(nokia.name);
console.log(Phone.name);
ES5的继承
function Phone(brand,price){
this.brand=brand;
this.price = price;
}
Phone.prototype.call = function(){
console.log("我可以打电话");
}
function SmartPhone(brand,price,color,size){
Phone.call(this,brand,price);
this.color = color;
this.size = size;
}
SmartPhone.prototype = new Phone;
// 下面这句可以不写
SmartPhone.prototype.constructor = SmartPhone;
SmartPhone.prototype.photo= function(){
console.log("我可以拍照");
}
SmartPhone.prototype.playgame= function(){
console.log("我可以完游戏");
}
const chuizi=new SmartPhone('锤子',2499,"黑色",'5.5inch')
console.log(chuizi);
ES6的类继承
// ES6的类继承
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);
this.color=color;
this.size=size;
}
photo(){
console.log("拍照");
}
playgame(){
console.log("玩游戏");
}
}
// 重载
call(){
super.call();
console.log('我可以进行视频通话');
}
const xiaomi = new SmartPhone('小米',799,'黑色','7inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playgame();
get和set
在class内部成员方法前加set 或者get,此时成员方法就变成了一个成员属性
class Phone{
get price(){
console.log("价格属性被读取了");
return "i love you"
}
set price(value){
console.log("new value =" , value );
}
}
const p=new Phone();
console.log(p.price);
p.price = 'fatux'
ES6的数值扩展
//js表示的最小精度,如果两个浮点数相减小于这个数,可以认为两个数相等。
console.log( Number.EPSILON);
//不同进制
let b=0b1010;
let o=0o777;
let d=100;
let x = 0xff;
// Number.isFinate //检测一个数值是否为有限数
// Number.isNan //检测一个数值是否为Nan
// Number.parseFloat
// Number.parseInt
console.log(Number.isInteger(5));
number.sign()
ES6对象方法的扩展
//1、Object.is 判断两个值是否完全相等
console.log(Object.is(11,11));
console.log(Object.is(NaN,NaN)); //true
//2、Object.assign 对象的合并
const config1 ={
host:'localhost',
port: 3306,
name: 'root',
pass: 'root',
test1: "test1"
};
const config2 = {
host: "http://www.baidu.com",
port: 33060,
name: "fatux",
pass: "i love you",
test2:"test2"
}
// 以config1为模板,用config2中的配置去覆盖config1中的值,没有的项会合并
Object.assign(config1,config2)
console.log(config1);
//3、Object.setPrototypeOf Object.getPrototypeof
const school ={
name:'fatux'
}
const cities ={
xiaoqu:['shanghai','beijing']
}
Object.setPrototypeOf(school,cities);
console.log(school);
console.log(Object.getPrototypeOf(school));
模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
模块化的好处:
- 防止命名冲突
- 代码复用
- 高维护性
ES6之前的模块化规范有:
CommonJs => NodeJS Browserify
AMD => requireJS
CMD => seaJS
ES6模块化语法
export 命令用于规定模块的对外接口
import 用于输入其他模块提供的功能
export 三种方式
// 分别暴露
export let school ='fatux';
export function teach(){
console.log("i can do sth");
}
// 集中暴露
let school='beimengxiaoxue';
function findJob(){
console.log("找工作");
}
export {
school,findJob
}
// 默认暴露
export default{
school: 'aituigu',
change: function(){
console.log("学到老");
}
}
import
// 通用的引入方法
import * as m1 from "./js/m1.js"
console.log(m1);
// 结构赋值的方式
import {school,findJob} from "./js/m2.js"
console.log(school);
// import {default as m3} from "./js/m3.js"
// console.log(m3);
// 简便形式,针对默认暴露
import m3 from "./js/m3.js"
m3.change();
ES6使用模块化方法2
html中指定src type设置成module 在入口文件app中统一引入
<script src="./js/app.js" type="module"></script>
import * as m1 from "./m1.js"
import * as m2 from "./m2.js"
import * as m3 from "./m3.js"
console.log(m1);
console.log(m2);
console.log(m3);
BABEL
为了解决浏览器兼容性问题,将ES6以上的新特性转换成ES5的写法,适配绝大多数浏览器。
1、安装 npm i babel-cli babel-preset-env browserify -D
2、编译: npx babel ./js -d dist/js --presets-babel-preset-env
PS D:\0 web前端\vue_basic\es6> npx babel ./js -d dist/js --presets-babel-preset-env
js\app.js -> dist\js\app.js
js\m1.js -> dist\js\m1.js
js\m2.js -> dist\js\m2.js
js\m3.js -> dist\js\m3.js
3打包 npx browserify dist/js/app.js -o dist/bundle.js
html 文件中引入bundle.js使用
npm引入jquery并使用jquery
npm -i jquery
import $ from "jquery"
$('body').css('background','pink')
我测试的时候报错。 以后再搞吧
第2章 ESMAScript7-新特性
ES7
2.1 Array.prototype.includes
检测数组中是否包含某个元素,返回布尔类型值
2.2 指数操作符 ** 幂运算
const mingzhu=['xiyouji','sanguo'];
console.log(mingzhu.includes('sanguo'));
console.log(mingzhu.includes('sanguo1'));
console.log(2 ** 10);
ES8
1、 async await
async和await两种语法结合可以让异步代码像同步代码一样
async函数
async函数的返回值是promise对象
promise对象的结果由async函数执行的返回值决定
<script>
// 返回的结果只要不是一个promise,那么就是一个成功的promise,默认是成功的
async function fn(){
// throw new Error('出错了')
return new Promise((resolve,reject)=>{
resolve('执行成功!')
})
}
const result = fn();
result.then(value =>{
console.log(value);
},reason => {
console.log(reason);})
</script>
fatux: 在promise外层又加了一个壳子。
await表达式
- await 必须写在async函数中
- await右侧的表达式一般为promise对象
- await 返回的是promise成功的值
- await的promise失败了,就会抛出异常,需要通过try…catch 捕获处理
// 返回的结果只要不是一个promise,那么就是一个成功的promise,默认是成功的
const p = new Promise((resolve,reject)=>{
reject('失败啦');
})
async function main(){
try {
let res = await p;
console.log(res);
}catch(e){
console.log(e);
}
}
main();
async和await结合读取文件: node 环境 执行
const fs = require('fs')
function read(){
return new Promise((resolve,reject)=>{
fs.readFile("../abc.txt",(err,data)=>{
if(err) reject(err);
resolve(data);
})
})
}
function read2(){
return new Promise((resolve,reject)=>{
fs.readFile("../abc.txt",(err,data)=>{
if(err) reject(err);
resolve(data);
})
})
}
async function main(){
let data = await read();
let data2 = await read2();
console.log(data.toString());
console.log(data2.toString());
}
main();
async和await 发送ajax请求
function sendAJAX(url){
return new Promise((resolve,reject)=>{
//1、创建对象
const x = new XMLHttpRequest();
//2 初始化
x.open("GET",url);
//3 发送
x.send();
//4 事件绑定
x.onreadystatechange=function(){
if (x.readyState ===4 ){
if(x.status>=200 && x.status<300 ){
resolve(x.response)
}else{
// 如果失败
reject(x.status);
}
}
}
})
}
//const ret = sendAJAX('http://www.baidu.com')
// sendAJAX('https://api.apiopen.top/getJoke').then(value =>{
// console.log(value);
// },reason=>{
// console.log(reason);
// })
async function main(){
let result = await sendAJAX("https://api.apiopen.top/getJoke")
let result2 = await sendAJAX("https://www.baidu.com")
console.log(result2);
}
main();
异步任务的演化大概就是让异步看上去像同步任务一样。
目前流行的处理方式:
async + await
2、 对象方法的扩展,Object.values和Object.entries
Object.values() 方法返回一个给定对象的所有可枚举属性值的数组
Object.entries() 方法返回一个给定对象自身可遍历属性[key,value]
entries返回一个二维数组,可以很方便的构建一个map
const o ={
name: 'fatux',
age:18,
sex:'男'
}
console.log(Object.keys(o));
console.log(Object.values(o));
console.log(Object.entries(o));
const m=new Map(Object.entries(o));
console.log(m);
// 获取对象自身属性的描述信息。
console.log(Object.getOwnPropertyDescriptors(o));
ES9
Rest参数与spread扩展运算符在ES6中已经引入,不过ES6中只针对数组
在ES9中为对象提供了像数组一样的rest参数和扩展运算符
对象可以像数组一样方便的组合在一起
const a={
a: 'aa'
}
const b={
b: 'bb'
}
const c={
c: 'cc'
}
const total ={...a,...b,...c}
console.log(total)
正则扩展-命名捕获分组
略 (用的时候再补充)
// let str = '<a href="http://www.atguigu.com"> 尚硅谷 </a>';
// // 提取Url与标签文本
// const reg = /<a href ="(.*)">(.*)<\/a>/;
// const result = reg.exec(str);
// console.log(result[1]);
// console.log(result[2]);
let str = '<a href="http://www.atguigu.com"> 尚硅谷 </a>';
// 提取Url与标签文本
const reg = /<a href ="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result);
正则扩展-反向断言
//正向断言
// let str="111#!@#@!!知道么555啦啦啦";
// const reg = /\d+(?=啦)/
// const result = reg.exec(str)
// console.log(result);
// 反向断言,根据前面的内容来判断
// const reg2= /(?<=么)\d+/
// let result2 = reg2.exec(str)
// console.log(result2);
正则扩展- dotAll模式
dot . 元字符, 除换行符以外的任意单个字符
ES10
Object.fromEntries 跟ES8中的Object.entries互为逆运算
const result = Object.fromEntries([
['name','fatux'],
['xueke','java,c,python']
])
// 也可以传入map对象
console.log(result);
trimStart trimEnd 清除一侧的空格
数组的两个方法: flat 和 flatMap
将多维数组转换为低维数组
// const arr = [1,2,3,4,[5,6]]
// console.log(arr.flat());
// const arr2 = [1,2,3,4,[5,6,[7,8,9]]]
// console.log(arr2.flat(10));
// flatMap
const arr3 = [1,2,3,4]
const result = arr3.map(item => item*10)
//const result = arr3.flatMap(item => [item*10])
console.log(result);
Symbol.prototype.descripton
let s=Symbol('aobo');
console.log(s.description)
ES11
私有属性 #开头
class Person{
name;
#age;
#weight;
constructor(name,age,weight){
this.name=name;
this.#age = age;
this.#weight =weight;
}
}
const girl = new Person('tao',37,110);
console.log(girl);
console.log(girl.name);
console.log(girl.age);
console.log(girl.weight);
Promise.allSettled
输入Promise数组,返回一个成功的promise,包含每个任务的状态和数据
Promise.all
输入Promise数组,只要有一个失败就失败,所有任务都成功才成功。
String.prototype.matchAll
正则扩展
可选链操作符
?. 当一个对象层级比较深
object?.db?.host //即使链中有一个对象为空也不会报错,返回undifined
动态import
import 函数返回一个promise对象,返回的数据就是加载好的模块,可以在then中调用模块中的方法
import('./hello.js').then(module=>{
module.hello();
})
加载需要读取文件,属于异步操作,所以用promise合理
bigint
let n=521n //数字后面加n
// 函数
let n=123;
console.log(Bigint(n));
// 大数据运算
global this
始终指向全局对象