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-299
            if (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 Phone
    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 实现

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.username
    password: 'root',   // user.password
    type: '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,任意一个失败都会返回失败的 promise

console.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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/376301.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ZigBee学习——在官方例程上实现串口通信

Z-Stack版本为3.0.2 IAR版本为10.10.1 文章目录 一、添加头文件二、定义接收缓冲区三、编写Uart初始化函数四、编写串口回调函数五、函数声明六、函数调用七、可能遇到的问题(function “halUartInit“ has no prototype) 以下所有操作都是在APP层进行&#xff0c;也就是这个文…

[Python 安装]

进入Python的官方下载页面 http://www.python.org/download/ 然后进行软件的下载 下载好之后点击exe会出现安装界面&#xff0c;接着进行安装&#xff0c;选择安装路径。 运行Python 安装成功后&#xff0c;打开命令提示符窗口&#xff08;winR,在输入cmd回车&#xf…

C程序训练:二分查找法的应用之2

本文来自&#xff1a;C程序训练&#xff1a;二分查找法的应用之2 在《C程序训练&#xff1a;二分查找法的应用》一文中介绍了利用二分查找计算某个区间中数的个数&#xff0c;本文介绍利用二分查找法计算数列中出现单个数字的位置。题目描述如下。 题目描述&#xff1a;一维整…

Python进阶--下载想要的格言(基于格言网的Python爬虫程序)

注&#xff1a;由于上篇帖子&#xff08;Python进阶--爬取下载人生格言(基于格言网的Python3爬虫)-CSDN博客&#xff09;篇幅长度的限制&#xff0c;此篇帖子对上篇做一个拓展延伸。 目录 一、爬取格言网中想要内容的url 1、找到想要的内容 2、抓包分析&#xff0c;找到想…

Netty源码系列 之 bind绑定流程 源码

Netty框架总览 Netty是一个基于NIO异步通信框架 Netty框架是由许多组件&#xff0c;优化的数据结构所构建成。 正是通过灵活的组件构建&#xff0c;优化后的数据结构&#xff0c;进而才能保证Netty框架面对高并发场景具有一定的能力 Netty相关组件 Netty重要的组件有&…

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

一、二叉树理论基础 1.存储方式 链式存储&#xff1a; 顺序存储&#xff1a; 2.二叉树标准定义(Java) public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {…

spring cloud stream

背景 主要解决不同消息中间件切换问题。实现不同中间件的代码解耦。 链接: 支持的中间件 后文使用kafka测试。 引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream</artifactId></depende…

微服务介绍、使用 Nacos 实现远程调用以及 OpenFeign 的使用

1 微服务的概念 区别于单体项目 单体项目拆分成微服务项目的目标&#xff1a;高内聚、低耦合 拆分思路 纵向拆分&#xff1a;根据功能模块 横向拆分&#xff1a;抽取可复用模块 2 微服务拆分——远程调用 背景&#xff1a;微服务单一职责&#xff0c;每个服务只有自己的功能…

电脑没有声音是怎么回事?几招快速解决

当电脑突然失去声音&#xff0c;这可能成为一种令人烦恼的体验&#xff0c;尤其是在你期望享受音乐、观看视频或进行在线会议的时候。幸运的是&#xff0c;大多数时候&#xff0c;电脑没有声音的问题是可以迅速解决的。电脑没有声音是怎么回事&#xff1f;本文将为你介绍一些常…

老是抓不准现货白银实时报价怎么办?

现货白银的实时报价是不断变动的&#xff0c;投资者要了解当下的现货白银实时走势&#xff0c;并且依靠对实时报价的分析预判未来的趋势&#xff0c;这是不容易的&#xff0c;但是不是不能做到呢&#xff1f;也不是。因为市场不是横盘就是趋势&#xff0c;只要有趋势&#xff0…

零代码3D可视化快速开发平台

老子云平台 老子云3D可视化快速开发平台&#xff0c;集云压缩、云烘焙、云存储云展示于一体&#xff0c;使3D模型资源自动输出至移动端PC端、Web端&#xff0c;能在多设备、全平台进行展示和交互&#xff0c;是全球领先、自主可控的自动化3D云引擎。此技术已经在全球申请了专利…

.NET Avalonia开源、免费的桌面UI库 - SukiUI

前言 今天分享一款.NET Avalonia基于MIT License协议开源、免费的桌面UI库&#xff1a;SukiUI。 Avalonia介绍 Avalonia是一个强大的框架&#xff0c;使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件&#xff0c;确保在Windows、macOS、Linux、An…

用云手机打造tiktok账号需要注意些什么?

随着tiktok平台的火热&#xff0c;越来越多的商家开始尝试更高效的tiktok运营方法。其中&#xff0c;tiktok云手机作为一种新科技引起了很多人的注意&#xff0c;那么用云手机运营tiktok需要注意些什么&#xff1f;下文将对此进行详细解析。 1. 不是所有的云手机都适合做tiktok…

跳过mysql密码并重置密码 shell脚本

脚本 目前只是验证了5.7 版本是可以的&#xff0c;8.多的还需要验证 以下是一个简单的Shell脚本&#xff0c;用于跳过MySQL密码设置并重置密码&#xff1a; #!/bin/bash yum install psmisc -y# 停止MySQL服务 sudo service mysqld stop# 跳过密码验证 sudo mysqld --skip-g…

通过 docker-compose 部署 Flink

概要 通过 docker-compose 以 Session Mode 部署 flink 前置依赖 Docker、docker-composeflink 客户端docker-compose.yml version: "2.2" services:jobmanager:image: flink:1.17.2ports:- "8081:8081"command: jobmanagervolumes:- ${PWD}/checkpoin…

分析伦敦银报价总失败?你试试这样

做伦敦银交易的投资者要先对伦敦银报价进行分析&#xff0c;但是有些投资者反映自己分析伦敦银报价总是失败&#xff0c;抓不住市场价格的变化趋势&#xff0c;为什么会这样呢&#xff1f;我们可以从以下这两个方面来考虑。 转变分析工具。为什么分析伦敦银报价总失败&#xff…

提升你的PHP开发效率:探索JetBrains PhpStorm 2022的全新特性

在当今快速发展的软件开发领域&#xff0c;选择一个强大且高效的开发工具对于提升开发效率、保证代码质量至关重要。对于PHP开发者来说&#xff0c;JetBrains PhpStorm一直是市场上最受欢迎的IDE之一。随着JetBrains PhpStorm 2022的发布&#xff0c;这款工具带来了一系列创新功…

蓝桥杯-求阶乘-python

问题描述 满足N!的末尾恰好有K个0的最小的N是多少&#xff1f; 如果这样的N不存在输出一1。 思路解析 末尾的0是由10产生的&#xff0c;而10是由质数2和5产生的 在求阶乘的过程中&#xff0c;只要是偶数就会有2&#xff0c;而5相对2更少&#xff0c;所以对于10的数量我们可以…

机器学习-梯度下降法

不是一个机器学习算法是一种基于搜索的最优化方法作用&#xff1a;最小化一个损失函数梯度上升法&#xff1a;最大化一个效用函数 并不是所有函数都有唯一的极值点 解决方法&#xff1a; 多次运行&#xff0c;随机化初始点梯度下降法的初始点也是一个超参数 代码演示 impor…

手势检测跟踪解决方案

美摄科技&#xff0c;作为业界领先的人工智能技术提供商&#xff0c;致力于为企业提供先进的手势检测与跟踪解决方案&#xff0c;以推动企业在智能化、高效化的道路上阔步前行。 一、手势检测与跟踪技术的优势 手势检测与跟踪技术作为人机交互的重要一环&#xff0c;具有以下…