当前位置: 首页 > news >正文

ES6 ~ ES11 学习笔记

·课程地址

ES6

let

let 不能重复声明变量(var 可以)

let a;
let b, c, d;
let e = 100;
let f = 521, g = "atguigu", h = [];

let 具有块级作用域,内层变量外层无法访问

let 不存在变量提升(运行前收集变量和函数,提前声明),但是 var 存在变量提升:

console.log(song);	// undefined
var song = "hello";

不影响作用域链:

{let school = "atguigu";function fn() {console.log(school);	// atguigu}fn();
}

案例:

<body><div class="container"><h2 class="page-header">点击切换颜色</h2><div class="item"></div><div class="item"></div><div class="item"></div></div><script>//获取div元素对象let items = document.getElementsByClassName('item');//遍历并绑定事件for (let i = 0; i < items.length; i++) {    // var 是不行的items[i].onclick = function () {//修改当前元素的背景颜色// this.style.background = 'pink';items[i].style.background = 'pink';}}</script>
</body>

如果在 for 循环中使用了 var 声明 i,那么它会被提升到全局作用域 window.i,回调函数调用时它的值一直是 3

const

  1. 一定要赋初始值
  2. 一般常量使用大写(潜规则)
  3. 常量的值不能修改
  4. 常量同样拥有块儿级作用域
  5. 对于数组和对象的元素修改,不算做对常量的修改,不会报错(地址不变)
const TEAM = ['UZI','MXLG','Ming','Letme'];
TEAM.push('Meiko');

解构赋值

数组解构:

const F4 = ['小沈阳','刘能','赵四','宋小宝'];
let [xiao, liu, zhao, song] = F4;	// 解构赋值
console.log(xiao);
console.log(liu);
console.log(zhao);
console.log(song);

对象解构:

const zhao = {name: '赵本山',age: '不详',xiaopin: function(){console.log("我可以演小品");}
};let {name, age, xiaopin} = zhao;	// 对象解构
console.log(name);
console.log(age);
console.log(xiaopin);
xiaopin();let {xiaopin} = zhao;
xiaopin();
let {xiaopin} = zhao;
xiaopin();

模板字符串

模板字符串内容中可以直接出现换行符

let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;

变量拼接:

let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员!!`;
console.log(out);

对象简化写法

用于属性名和变量值相同的情况

let name = '尚硅谷';
let change = function () {console.log('我们可以改变你!!');
}const school = {name,change,improve() {console.log("我们可以提高你的技能");}
}

箭头函数

let fn = (a, b) => {return a + b;
}

注意事项:箭头函数的 this 是静态的。this 始终指向函数声明时所在作用域下的 this 的值。不能使用 call 切换 this 指向

function getName() {console.log(this.name);
}
let getName2 = () => {console.log(this.name);
}//设置 window 对象的 name 属性
window.name = '尚硅谷';
const school = {name: "ATGUIGU"
}getName();   // window.name = '尚硅谷';
getName2();  // window.name = '尚硅谷';getName.call(school);    // name: "ATGUIGU"
getName2.call(school);   // window.name = '尚硅谷';
  • 不能作为构造实例化对象
  • 不能使用 arguments 变量
  • 当代码体只有一条语句的时候, 此时 return 必须省略,语句的执行结果就是函数的返回值
let double = n => n + n;

案例:点击 div 后等待 2s 后变色

传统写法:

let ad = document.getElementById('ad');
ad.addEventListener("click", function () {let _this = this;setTimeout(function() {_this.style.background = 'pink';}, 2000);
});

使用箭头函数的写法:

let ad = document.getElementById('ad');
ad.addEventListener("click", function () {setTimeout(() => {this.style.background = 'pink';}, 2000);
});

案例 2:从数组返回偶数元素

const arr = [1,6,9,10,100,25];
const result = arr.filter(item => item % 2 === 0);

箭头函数适合与 this 无关的回调:定时器,数组的方法回调
箭头函数不适合与 this 有关的回调:事件回调,对象的方法

函数默认参数

ES6 允许给函数参数赋初始值,一般位置要靠后

function add(a, b, c = 10) {return a + b + c;
}

与解构赋值结合:

function connect({ host = "127.0.0.1", username, password, port }) {console.log(host)console.log(username)console.log(password)console.log(port)
}
connect({host: 'atguigu.com',username: 'root',password: 'root',port: 3306
});

rest 参数

类似于 arguments,用于支持函数的不定参数

ES5 写法:

function date() {console.log(arguments);
}
date('白芷', '阿娇', '思慧');

使用 rest 参数:

function date(...args) {	// args 是一个数组console.log(args);  // filter some every map 
}
date('阿娇', '柏芝', '思慧');// rest 参数必须要放到参数最后
function fn(a, b, ...args) {console.log(a);console.log(b);console.log(args);
}
fn(1, 2, 3, 4, 5, 6);

扩展运算符

数组解构:

const arr = [1, 2, 3];
function fn() {console.log(arguments);
}
fn(...arr);		// fn(1, 2, 3);

数组拼接:

const kuaizi = ['王太利', '肖央'];
const fenghuang = ['曾毅', '玲花'];
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];

数组拷贝:

const sanzhihua = ['E', 'G', 'M'];
const sanyecao = [...sanzhihua];//  ['E','G','M']
console.log(sanyecao);

将伪数组转化为真正的数组:

const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);	// arguments

Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JS 的第七种数据类型,是一种类似于字符串的数据类型

Symbol 的特点:

  • 值唯一,用来解决命名冲突的问题
  • 不能与其他数据进行运算
  • Symbol 定义的对象属性不能用 for in 循环遍历,但可以使用 Reflect.ownkeys 来获取对象的所有键名
//创建Symbol
let s = Symbol();
// console.log(s, typeof s);
let s2 = Symbol('尚硅谷');
let s3 = Symbol('尚硅谷');
//Symbol.for 创建
let s4 = Symbol.for('尚硅谷');
let s5 = Symbol.for('尚硅谷');

JS 七大数据类型

USONB you are so niubility

  • u undefined
  • s string symbol
  • o object
  • n null number
  • b boolean

Symbol 的作用:给对象添加独一无二的属性或方法

let youxi = {name:"狼人杀",[Symbol('say')]: function(){console.log("我可以发言")},[Symbol('zibao')]: function(){console.log('我可以自爆');}
}

在这里插入图片描述

Iterator

迭代器是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署了 Itertor 接口,就可以完成遍历操作

获取数组的迭代器:

let it = arr[Symbol.iterator]();
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];// 使用 for...of 遍历数组
for(let v of xiyou){console.log(v);
}let iterator = xiyou[Symbol.iterator]();//调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

自定义迭代器:返回一个对象,其具有 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 提供的一种异步编程解决方案

function * gen(){// console.log(111);yield '一只没有耳朵';// console.log(222);yield '一只没有尾部';// console.log(333);yield '真奇怪';// console.log(444);
}let iterator = gen();
console.log(iterator.next());	// {value: v, done: false}
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());//遍历
for(let v of gen()){	// 一只没有……console.log(v);
}

生成器函数参数

function* gen(arg) {console.log(arg);let one = yield 111;console.log(one);let two = yield 222;console.log(two);let three = yield 333;console.log(three);
}//执行获取迭代器对象
let iterator = gen('AAA');
console.log(iterator.next());   // "AAA", {value: 111, done: false}
//next方法可以传入实参
console.log(iterator.next('BBB'));  // one
console.log(iterator.next('CCC'));  // two
console.log(iterator.next('DDD'));  // three

生成器函数实例:使用定时器,1s 后控制台输出 111 2s后输出 222 3s后输出 333

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();	// 调用下一个定时器:{value: undefined, done: true}},3000)
}function * gen(){yield one();yield two();yield three();
}//调用生成器函数
let iterator = gen();
iterator.next();

生成器函数实例2:

//模拟获取  用户数据  订单数据  商品数据 
function getUsers() {setTimeout(() => {let data = '用户数据';//调用 next 方法, 并且将数据传入iterator.next(data);}, 1000);
}function getOrders() {setTimeout(() => {let data = '订单数据';iterator.next(data);}, 1000)
}function getGoods() {setTimeout(() => {let data = '商品数据';iterator.next(data);}, 1000)
}function* gen() {let users = yield getUsers();let orders = yield getOrders();let goods = yield getGoods();
}//调用生成器函数
let iterator = gen();
iterator.next();

Promise

Promise 用于异步编程,语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

//实例化 Promise 对象
const p = new Promise(function (resolve, reject) {setTimeout(function () {//// let data = '数据库中的用户数据';// resolve// resolve(data);let err = '数据读取失败';reject(err);}, 1000);
});//调用 promise 对象的 then 方法
p.then(function (value) {console.log(value);
}, function (reason) {console.error(reason);
})

Promise 读取文件案例:

const fs = require('fs');const p = new Promise(function(resolve, reject) {fs.readFile("path", (err, data) => {if (err) reject(err);else resolve(data);});
});p.then(value => console.log(value.toString()),reason => console.warn("error!!")
);

Promise 封装 AJAX:

// 接口地址: https://api.apiopen.top/getJoke
const p = new Promise((resolve, reject) => {//1. 创建对象const xhr = new XMLHttpRequest();//2. 初始化xhr.open("GET", "https://api.apiopen.top/getJ");//3. 发送xhr.send();//4. 绑定事件, 处理响应结果xhr.onreadystatechange = function () {//判断if (xhr.readyState === 4) {//判断响应状态码 200-299if (xhr.status >= 200 && xhr.status < 300) {//表示成功resolve(xhr.response);} else {//如果失败reject(xhr.status);}}}
})//指定回调
p.then(function (value) {console.log(value);
}, function (reason) {console.error(reason);
});

调用 then 方法 then方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定

如果回调函数中返回的结果是 非 promise 类型的属性,状态为成功,返回值为对象的成功的值:

const result = p.then(value => {console.log(value);//2. 非 promise 类型的属性return 'iloveyou';
}, reason => {console.warn(reason);
});

如果返回值是 Promise 类型的对象,则直接返回:

const result = p.then(value => {console.log(value);//3. 是 promise 对象return new Promise((resolve, reject)=>{// resolve('ok');reject('error');});
}, reason => {console.warn(reason);
});

如果抛出错误,则返回一个 reject 的 Promise:

const result = p.then(value => {console.log(value);throw '出错啦!';
}, reason => {console.warn(reason);
});

Promise 读取多个文件:

const p = new Promise((resolve, reject) => {fs.readFile("./resources/为学.md", (err, data) => {resolve(data);});
});p.then(value => {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧诗.md", (err, data) => {resolve([value, data]);});});
}).then(value => {return new Promise((resolve, reject) => {fs.readFile("./resources/观书有感.md", (err, data) => {//压入value.push(data);resolve(value);});})
}).then(value => {console.log(value.join('\r\n'));
});

catch:指定 Promise 失败回调

const p = new Promise((resolve, reject)=>{setTimeout(()=>{//设置 p 对象的状态为失败, 并设置失败的值reject("出错啦!");}, 1000)
});// p.then(function(value){}, function(reason){
//     console.error(reason);
// });p.catch(function(reason){console.warn(reason);
});

Set

//声明一个 set
let s = new Set();
let s2 = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿']);//元素个数
console.log(s2.size);
//添加新的元素
s2.add('喜事儿');
//删除元素
s2.delete('坏事儿');
//检测
console.log(s2.has('糟心事'));
//清空
s2.clear();
// console.log(s2);for (let v of s2) {console.log(v);
}

Set 实践:

去重:

let arr = [1,2,3,4,5,4,3,2,1];
//1. 数组去重
let result = [...new Set(arr)];

交集:

let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item));

并集:

let union = [...new Set([...arr, ...arr2])];

差集:

let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));

Map

//声明 Map
let m = new Map();//添加元素
m.set('name', '尚硅谷');
m.set('change', function () {console.log("我们可以改变你!!");
});
let key = {school: 'ATGUIGU'
};
m.set(key, ['北京', '上海', '深圳']);//size
console.log(m.size);//删除
m.delete('name');//获取
console.log(m.get('change'));
console.log(m.get(key));//清空
m.clear();//遍历
for (let v of m) {console.log(v);
}

class

//手机
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);//class
class Shouji {//构造方法 名字不能修改constructor(brand, price) {this.brand = brand;this.price = price;}//方法必须使用该语法, 不能使用 ES5 的对象完整形式call() {console.log("我可以打电话!!");}
}let onePlus = new Shouji("1+", 1999);console.log(onePlus);

静态成员:

class Phone {static name = "shouji";static change() {console.log("i can change the world");}
}conosle.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 bind to Phonethis.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 实现

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);// Phone.call(this, brand, price)this.color = color;this.size = size;}photo(){console.log("拍照");}playGame(){console.log("玩游戏");}call(){		// 方法重写console.log('我可以进行视频通话');}
}const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();

get 和 set

// get 和 set  
class Phone {get price() {console.log("价格属性被读取了");return 'iloveyou';}set price(newVal) {  // 必须有形参console.log('价格属性被修改了');}
}//实例化对象
let s = new Phone();// console.log(s.price);
s.price = 'free';

数值扩展

//0. Number.EPSILON 是 JavaScript 表示的最小精度
//EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16
function equal(a, b) {if (Math.abs(a - b) < Number.EPSILON) {return true;} else {return false;}
}
console.log(0.1 + 0.2 === 0.3);
console.log(equal(0.1 + 0.2, 0.3))//1. 二进制和八进制
let b = 0b1010;
let o = 0o777;
let d = 100;
let x = 0xff;
console.log(x);//2. Number.isFinite  检测一个数值是否为有限数
console.log(Number.isFinite(100));
console.log(Number.isFinite(100 / 0));
console.log(Number.isFinite(Infinity));//3. Number.isNaN 检测一个数值是否为 NaN 
console.log(Number.isNaN(123));//4. Number.parseInt Number.parseFloat字符串转整数
console.log(Number.parseInt('5211314love'));
console.log(Number.parseFloat('3.1415926神奇'));//5. Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(5));
console.log(Number.isInteger(2.5));//6. Math.trunc 将数字的小数部分抹掉  
console.log(Math.trunc(3.5));//7. Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100));
console.log(Math.sign(0));
console.log(Math.sign(-20000));

对象方法扩展

//1. Object.is 判断两个值是否完全相等 
console.log(Object.is(120, 120));   // true
console.log(Object.is(NaN, NaN));   // true
console.log(NaN === NaN);   // false//2. Object.assign 对象的合并
const config1 = {host: 'localhost',port: 3306,name: 'root',pass: 'root',test: 'test'
};
const config2 = {host: 'http://atguigu.com',port: 33060,name: 'atguigu.com',pass: 'iloveyou',test2: 'test2'
}
// config2 覆盖了 config1
console.log(Object.assign(config1, config2));//3. Object.setPrototypeOf 设置原型对象  Object.getPrototypeof
const school = {name: '尚硅谷'
}
const cities = {xiaoqu: ['北京', '上海', '深圳']
}
Object.setPrototypeOf(school, cities);
console.log(Object.getPrototypeOf(school));
console.log(school);

模块化

分别暴露:

// m1.js
export let school = '尚硅谷';export function teach() {console.log("我们可以教给你开发技能");
}

导入:

import * as m1 from "./src/js/m1.js";

统一暴露:

let school = '尚硅谷';function findJob(){console.log("我们可以帮助你找工作!!");
}export {school, findJob};

默认暴露:

export default {school: 'ATGUIGU',change: function(){console.log("我们可以改变你!!");}
}

引入模块:

//2. 解构赋值形式
import { school, teach } from "./src/js/m1.js";
import { school as guigu, findJob } from "./src/js/m2.js";
import { default as m3 } from "./src/js/m3.js";//3. 简便形式  针对默认暴露
import m3 from "./src/js/m3.js";
console.log(m3);

在入口文件统一引入:

// app.js
//模块引入
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";

Babel

Babel 是一个 JavaScript 编译器,将高版本的 ES 代码编译为 ES5

安装打包工具:

npm i babel-cli babel-preset-env browserify -D

编译:

npx babel src/js -d dist/js --presets=babel-preset-env

打包:

npx browserify dist/js/app.js -o dist/bundle.js

模块化引入 NPM 包:

在入口文件导入 jquery

import $ from 'jquery';// const $ = require("jquery");
$('body').css('background','pink');

重新编译并打包

ES7

Array.prototype.includes

检测数组中是否包含某个元素

指数操作符

console.log(2 ** 10);   // 1024
console.log(Math.pow(2, 10));

ES8

async 和 await

async 和 await 两种语法结合可以让异步代码像同步代码一样

async 函数

  • async 函数的返回值是 promise 对象
  • promise 对象的结果由 async 函数执行的返回值决定
//async 函数
async function fn() {// return '尚硅谷';// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象// return;//抛出错误, 返回的结果是一个失败的 Promise// throw new Error('出错啦!');//返回的结果如果是一个 Promise 对象return new Promise((resolve, reject) => {resolve('成功的数据');// reject("失败的错误");});
}const result = fn();//调用 then 方法
result.then(value => {console.log(value);
}, reason => {console.warn(reason);
})

await 函数

  • await 必须写在 async 函数中
  • await 右侧的表达式一般为 promise 对象
  • await 返回的是 promise 成功的值
  • await 的 promise 失败了,就会抛出异常,需要通过 try catch 处理
//创建 promise 对象
const p = new Promise((resolve, reject) => {// resolve("用户数据");reject("失败啦!");
})// await 要放在 async 函数中.
async function main() {try {let result = await p;//console.log(result);} catch (e) {console.log(e);}
}
//调用函数
main();

案例:async 和 await 读取文件内容

//1. 引入 fs 模块
const fs = require("fs");//读取『为学』
function readWeiXue() {return new Promise((resolve, reject) => {fs.readFile("./resources/为学.md", (err, data) => {//如果失败if (err) reject(err);//如果成功resolve(data);})})
}function readChaYangShi() {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧诗.md", (err, data) => {//如果失败if (err) reject(err);//如果成功resolve(data);})})
}function readGuanShu() {return new Promise((resolve, reject) => {fs.readFile("./resources/观书有感.md", (err, data) => {//如果失败if (err) reject(err);//如果成功resolve(data);})})
}//声明一个 async 函数
async function main(){//获取为学内容let weixue = await readWeiXue();//获取插秧诗内容let chayang = await readChaYangShi();// 获取观书有感let guanshu = await readGuanShu();console.log(weixue.toString());console.log(chayang.toString());console.log(guanshu.toString());
}main();

案例2:await 和 async 发送 ajax 请求

// 发送 AJAX 请求, 返回的结果是 Promise 对象
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);}}}})
}//promise then 方法测试
// sendAJAX("https://api.apiopen.top/getJoke").then(value=>{
//     console.log(value);
// }, reason=>{})// async 与 await 测试  axios
async function main() {//发送 AJAX 请求let result = await sendAJAX("https://api.apiopen.top/getJoke");//再次测试let tianqi = await sendAJAX('https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P')console.log(tianqi);
}main();

Object.values 和 Object.entries

//声明对象
const school = {name: "尚硅谷",cities: ['北京', '上海', '深圳'],xueke: ['前端', 'Java', '大数据', '运维']
};//获取对象所有的键
console.log(Object.keys(school));   // [ 'name', 'cities', 'xueke' ]
//获取对象所有的值
console.log(Object.values(school)); //[ '尚硅谷', [ '北京', '上海', '深圳' ], [ '前端', 'Java', '大数据', '运维' ] ]
//entries
console.log(Object.entries(school));    // [[k, v]]
//创建 Map
const m = new Map(Object.entries(school));
console.log(m.get('cities'));

Object.getOwnPropertyDescriptors

//对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));const obj = Object.create(null, {name: {//设置值value: '尚硅谷',//属性特性writable: true,configurable: true,enumerable: true}
});

ES9

Rest 参数与扩展运算符

// rest 参数
function connect({ host, port, ...user }) {console.log(host);console.log(port);console.log(user);
}connect({host: '127.0.0.1',port: 3306,username: 'root',   // user.usernamepassword: 'root',   // user.passwordtype: 'master'      // user.type
});// 对象合并
const skillOne = {q: '天音波'
}const skillTwo = {w: '金钟罩'
}const skillThree = {e: '天雷破'
}
const skillFour = {r: '猛龙摆尾'
}const mangseng = { ...skillOne, ...skillTwo, ...skillThree, ...skillFour };console.log(mangseng)

正则

命名捕获分组

传统的使用位置捕获分组:

//声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';// //提取 url 与 『标签文本』
const reg = /<a href="(.*)">(.*)<\/a>/;// //执行
const result = reg.exec(str);console.log(result);
console.log(result[1]);
console.log(result[2]);

使用命名捕获分组:

let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
//分组命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;const result = reg.exec(str);console.log(result.groups.url);console.log(result.groups.text);

反向断言

正向断言:

//声明字符串
let str = 'JS5211314你知道么555啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);

反向断言:

//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str);
console.log(result);

dotAll 模式

js 中的 . 是一个元字符,它能匹配除换行符以外的任意单个字符

dotAll 模式就是在模式后面增加模式修饰符 s,令 . 能够匹配换行符和空格(任意字符)。相当于用 \s+ 替换了 .*?

//dot  .  元字符  除换行符以外的任意单个字符
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>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;  // no dotall
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;   // use dotall
//执行匹配
// const result = reg.exec(str);
let result;
let data = [];
while (result = reg.exec(str)) {data.push({ title: result[1], time: result[2] });
}
//输出结果
console.log(data);

ES10

Object.fromEntries

从二维数组或 Map 中构造对象

const result = Object.fromEntries([['name','尚硅谷'],['xueke', 'Java,大数据,前端,云计算']
]);
const m = new Map();
m.set('name','ATGUIGU');
const result = Object.fromEntries(m);
const arr = Object.entries({name: "尚硅谷"
})
console.log(arr);

Object.entries()Object.fromEntries() 互为逆运算

// trim
let str = '   iloveyou   ';console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());

flat 与 flatMap

用于展平数组,其接受一个参数,指明展平数组的维度

//flat 平
//将多维数组转化为低位数组
// const arr = [1,2,3,4,[5,6]];
const arr = [1, 2, 3, 4, [5, 6, [7, 8, 9]]];
//参数为深度 是一个数字
console.log(arr.flat(2));
//flatMap
const arr = [1, 2, 3, 4];
const result = arr.flatMap(item => [item * 10]);
console.log(result);

Symbol.prototype.description

获取创建 Symbol 时的字符串:

//创建 Symbol
let s = Symbol('尚硅谷');
console.log(s.description);

ES11

私有属性

# 开头

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);console.log(this.#weight);}
}//实例化
const girl = new Person('晓红', 18, '45kg');console.log(girl.name);
// console.log(girl.#age);
// console.log(girl.#weight);girl.intro();

Promise.allSettled

接受一个 promise 数组,返回一个 promise 对象。对象中包含了全部结束的 promise

//声明两个promise对象
const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('商品数据 - 1');}, 1000)
});const p2 = new Promise((resolve, reject) => {setTimeout(() => {resolve('商品数据 - 2');// reject('出错啦!');}, 1000)
});//调用 allsettled 方法
// const result = Promise.allSettled([p1, p2]); // 返回全部结束的 promise// const res = Promise.all([p1, p2]);   // 全部成功才会返回成功的 promise,任意一个失败都会返回失败的 promiseconsole.log(res);

String.prototype.matchAll

用于得到正则批量匹配的结果

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(let v of result){console.log(v);
}const arr = [...result];console.log(arr);

可选链操作符

避免了层层判断一个对象是否具有某属性

// ?.
function main(config) {// const dbHost = config && config.db && config.db.host;const dbHost = config?.db?.host;console.log(dbHost);
}main({db: {host: '192.168.1.100',username: 'root'},cache: {host: '192.168.1.200',username: 'admin'}
})

动态 import

用于动态地从文件中加载模块,用时加载,提高了运行效率

import 返回的是一个 promise 对象

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>动态 import </title>
</head>
<body><button id="btn">点击</button><script src="./js/app.js" type="module"></script>
</body>
</html>
// app.js
// import * as m1 from "./hello.js";
//获取元素
const btn = document.getElementById('btn');btn.onclick = function(){import('./hello.js').then(module => {module.hello();});
}
// hello.js
export function hello(){alert('Hello');
}

bigint

在数字后面加 n

let n = 521n;
console.log(n, typeof(n));

BigInt 用于将一个数字构造为 BigInt

let n = 123;
console.log(BigInt(n));

BigInt 可以用于大数运算

let max = Number.MAX_SAFE_INTEGER;
console.log(max);
console.log(max + 1);
console.log(max + 2);console.log(BigInt(max))
console.log(BigInt(max) + BigInt(1))
console.log(BigInt(max) + BigInt(2))

globalThis

浏览器下指向 window;nodejs 下指向 global

相关文章:

ES6 ~ ES11 学习笔记

课程地址 ES6 let let 不能重复声明变量&#xff08;var 可以&#xff09; let a; let b, c, d; let e 100; let f 521, g "atguigu", h [];let 具有块级作用域&#xff0c;内层变量外层无法访问 let 不存在变量提升&#xff08;运行前收集变量和函数&#…...

001 - Hugo, 创建一个网站

001 - Hugo, 创建一个网站安装hugoWindows系统Macos Hugo博客搭建初始化博客主题安装配置博客各个页面开始创作创建 GitHub Page 仓库本地调试和预览发布内容 教程及鸣谢文字教程视频教程 001 - Hugo, 创建一个网站 这篇文章假设你已经&#xff1a; 了解基本的终端命令行知识&…...

前端开发:Vue框架与前端部署

Vue Vue是一套前端框架&#xff0c;免除原生)avaScript中的DOM操作&#xff0c;简化书写。是基于MVVM(Model–View-ViewModel)思想&#xff0c;实现数据的双向绑定&#xff0c;将编程的关注点放在数据上。简单来说&#xff0c;就是数据变化的时候, 页面会自动刷新, 页面变化的时…...

【leetcode】深搜、暴搜、回溯、剪枝(C++)3

深搜、暴搜、回溯、剪枝&#xff08;C&#xff09;3 一、解数独1、题目描述2、代码3、解析 二、单词搜索1、题目描述2、代码3、解析 三、黄金矿工1、题目描述2、代码3、解析 四、不同路径III1、题目描述2、代码3、解析 一、解数独 1、题目描述 leetcode链接 2、代码 class…...

社区养老|社区养老服务系统|基于springboot社区养老服务系统设计与实现(源码+数据库+文档)

社区养老服务系统目录 目录 基于springboot社区养老服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员部分功能 &#xff08;1&#xff09; 用户管理 &#xff08;2&#xff09;服务种类管理 &#xff08;3&#xff09;社区服务管理 &#xff08…...

云计算基础-存储虚拟化(深信服aSAN分布式存储)

什么是存储虚拟化 分布式存储是利用虚拟化技术 “池化”集群存储卷内通用X86服务器中的本地硬盘&#xff0c;实现服务器存储资源的统一整合、管理及调度&#xff0c;最终向上层提供NFS、ISCSI存储接口&#xff0c;供虚拟机根据自身的存储需求自由分配使用资源池中的存储空间。…...

数学实验第三版(主编:李继成 赵小艳)课后练习答案(十二)(3)

实验十二&#xff1a;微分方程模型 练习三 1.分别用数值解命令ode23t和ode45 计算示例3中微分方程的数值解,同用命令ode23 算得的数值解以及解析解比较,哪种方法精度较高?你用什么方法比较它们之间的精度? clc;clear; f(x,y)2*yx2; figure(1) [x,y]ode23t(f,[1,2],1); plo…...

CSS Transition:为网页元素增添优雅过渡效果

随着互联网的发展&#xff0c;网页的视觉效果和用户体验变得尤为重要。CSS Transition作为一种能够让网页元素在状态改变时呈现平滑过渡效果的工具&#xff0c;受到了广大前端开发者的青睐。本文将详细介绍CSS Transition的基本概念、使用方法以及常见应用&#xff0c;帮助读者…...

JDK 17 新特性 (一)

既然 Springboot 3.0 强制使用 JDK 17 那就看看 JDK17 有哪些新特性吧 参考链接 介绍一下 新特性的历史渊源 JDK 17是Java Development Kit&#xff08;JDK&#xff09;的一个版本&#xff0c;它是Java编程语言的一种实现。JDK 17于2021年9月14日发布&#xff0c;并作为Java …...

杨中科 ASP.NET DI综合案例

综合案例1 需求说明 1、目的:演示DI的能力; 2、有配置服务、日志服务&#xff0c;然后再开发一个邮件发送器服务。可以通过配置服务来从文件、环境变量、数据库等地方读取配置&#xff0c;可以通过日志服务来将程序运行过程中的日志信息写入文件、控制台、数据库等。 3、说明…...

蓝桥杯嵌入式第12届真题(完成) STM32G431

蓝桥杯嵌入式第12届真题(完成) STM32G431 题目 程序 main.c /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief : Main program body**************************…...

C#系列-多线程(4)

在C#中&#xff0c;多线程编程主要涉及使用System.Threading命名空间下的类和接口来创建和管理线程。以下是一些C#多线程编程的基本用法和示例&#xff1a; 1. 使用Thread类创建线程 csharp代码 using System; using System.Threading; class Program { static void …...

VS如何调试C运行时库

C运行时库(简称crt)是C标准库等组件的基础, 其会在进入main函数之前运行一些代码, 包括但不限于初始化堆栈, 内存分配等操作     这些代码是可以随着VC工具集一起安装到我们本地的。看一下这个情况, 就是VS调试器没找到对应的crt源码的情况, 调用堆栈是空的。为了解决这个问…...

软件工程师,超过35岁怎么办

概述 随着科技行业的飞速发展&#xff0c;软件开发工程师的职业道路充满了各种机遇和挑战。对于已经在这个行业摸爬滚打了十多年的软件开发工程师来说&#xff0c;当他们步入35岁这个年纪时&#xff0c;可能会感到一些迷茫和焦虑。许多人担忧&#xff0c;在以创新、活力、快速迭…...

通过 Prometheus 编写 TiDB 巡检脚本(脚本已开源,内附链接)

作者丨 caiyfc 来自神州数码钛合金战队 神州数码钛合金战队是一支致力于为企业提供分布式数据库 TiDB 整体解决方案的专业技术团队。团队成员拥有丰富的数据库从业背景&#xff0c;全部拥有 TiDB 高级资格证书&#xff0c;并活跃于 TiDB 开源社区&#xff0c;是官方认证合作伙…...

sql语句学习(一)--查询

【有道云笔记】基本sql语句2—查询基础 数据库表结构 DROP TABLE IF EXISTS class; CREATE TABLE class (id int(11) NOT NULL AUTO_INCREMENT,class_num varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 班级号,class_name varchar(255) CHARACTE…...

【HTML】交友软件上照片的遮罩是如何做的

笑谈 我不知道大家有没有在夜深人静的时候感受到孤苦难耐&#xff0c;&#x1f436;。于是就去下了一些交友软件来排遣寂寞。可惜的是&#xff0c;有些交友软件真不够意思&#xff0c;连一些漂亮小姐姐的图片都要进行遮罩&#xff0c;完全不考虑兄弟们的感受,&#x1f620;。所…...

【Java EE初阶十二】网络编程TCP/IP协议(一)

1. 网络编程 通过网络&#xff0c;让两个主机之间能够进行通信->就这样的通信来完成一定的功能&#xff0c;进行网络编程的时候&#xff0c;需要操作系统给咱们提供一组API&#xff0c;通过这些API来完成编程&#xff1b;API可以认为是应用层和传输层之间交互的路径&#xf…...

element-ui解决上传文件时需要携带请求数据的问题

一、问题描述 在前端使用element-ui进行文件上传时&#xff0c;需要携带请求头信息&#xff0c;比如Token。 二、问题解决 1. 表单实现 action置空添加:http-request属性覆盖默认的上传行为&#xff0c;实现自定义上传文件。注意:src后的图片路径如果是个网络请求(外链)&…...

【AI视野·今日NLP 自然语言处理论文速览 第七十九期】Thu, 18 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 18 Jan 2024 Totally 35 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deciphering Textual Authenticity: A Generalized Strategy through the Lens of Large Language Semantics …...

Docker容器运行

1、通过--name参数显示地为容器命名&#xff0c;例如:docker run --name “my_http_server” -d httpd 2、容器重命名可以使用docker rename。 3、两种进入容器的方法&#xff1a; 3.1、Docker attach 例如&#xff1a; 每间隔一秒打印”Hello World”。 Sudo docker run…...

【计算机网络】网络层之IP协议

文章目录 1.基本概念2.协议头格式3.网段划分4.特殊的IP地址5.IP地址的数量限制6.私有IP地址和公网IP地址7.路由 1.基本概念 IP地址是定位主机的&#xff0c;具有一个将数据报从A主机跨网络可靠的送到B主机的能力。 但是有能力就一定能做到吗&#xff0c;只能说有很大的概率。…...

2024/2/17 图论 最短路入门 dijkstra 1

目录 算法思路 Dijkstra求最短路 AcWing 849. Dijkstra求最短路 I - AcWing 850. Dijkstra求最短路 II - AcWing题库 最短路 最短路 - HDU 2544 - Virtual Judge (vjudge.net) 【模板】单源最短路径&#xff08;弱化版&#xff09; P3371 【模板】单源最短路径&#xf…...

交通管理|交通管理在线服务系统|基于Springboot的交通管理系统设计与实现(源码+数据库+文档)

交通管理在线服务系统目录 目录 基于Springboot的交通管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、驾驶证业务管理 3、机动车业务管理 4、机动车业务类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计…...

最适合初学者的Python入门详细攻略,一文讲清,赶紧收藏!

前言 目前python可以说是一门非常火爆的编程语言&#xff0c;应用范围也非常的广泛&#xff0c;工资也挺高&#xff0c;未来发展也极好。 Python究竟应该怎么学呢&#xff0c;我自己最初也是从零基础开始学习Python的&#xff0c;给大家分享Python的学习思路和方法。一味的买…...

幻兽帕鲁新手游戏攻略分享

在幻兽帕鲁中&#xff0c;提高实力是玩家不断追求的目标。以下是一些提高实力的攻略&#xff1a; 1、升级和进化&#xff1a;通过战斗和完成任务&#xff0c;玩家可以获得经验值&#xff0c;提升自己的等级。随着等级的提升&#xff0c;玩家可以获得技能点&#xff0c;用于提升…...

代码随想录算法训练营DAY19 | 二叉树 (6)

一、LeetCode 654 最大二叉树 题目链接&#xff1a;654.最大二叉树https://leetcode.cn/problems/maximum-binary-tree/ 思路&#xff1a;坚持左开右闭原则&#xff0c;递归划分数组元素生成左右子树。 class Solution {public TreeNode constructMaximumBinaryTree(int[] num…...

【C++】实现Date类的各种运算符重载

上一篇文章只实现了operator操作符重载&#xff0c;由于运算符较多&#xff0c;该篇文章单独实现剩余所有的运算符重载。继续以Date类为例&#xff0c;实现运算符重载&#xff1a; 1.Date.h #pragma once#include <iostream> #include <assert.h>using namespace …...

【Linux】程序地址空间 -- 详解 Linux 2.6 内核进程调度队列 -- 了解

一、程序地址空间回顾 在学习 C/C 时&#xff0c;我们知道内存会被分为几个区域&#xff1a;栈区、堆区、全局/静态区、代码区、字符常量区等。但这仅仅是在语言层面上的理解&#xff0c;是远远不够的。 如下空间布局图&#xff0c;请问这是物理内存吗&#xff1f; 不是&…...

10-通用类型、特质和生命周期

上一篇&#xff1a; 09-错误处理 每种编程语言都有有效处理概念重复的工具。在 Rust 中&#xff0c;泛型就是这样一种工具&#xff1a;具体类型或其他属性的抽象替身。我们可以表达泛型的行为或它们与其他泛型的关系&#xff0c;而不需要知道在编译和运行代码时它们的位置。 函…...